2013-08-07 131 views
0

我對Java完全陌生,我決定通過做一個小項目來學習它。我需要使用zlib壓縮一些字符串並將其寫入文件。但是,文件變得太大了。下面是代碼示例:Zlib壓縮的尺寸太大了

String input = "yasar\0yasar"; // test input. Input will have null character in it. 
byte[] compressed = new byte[100]; // hold compressed content 

Deflater compresser = new Deflater(); 
compresser.setInput(input.getBytes()); 
compresser.finish(); 
compresser.deflate(compressed); 
File test_file = new File(System.getProperty("user.dir"), "test_file"); 
try { 
    if (!test_file.exists()) { 
     test_file.createNewFile(); 
    } 
    try (FileOutputStream fos = new FileOutputStream(test_file)) { 
     fos.write(compressed); 
    } 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

這寫一個1千字節文件,而該文件應該最多是11個字節(因爲它的內容是在這裏11個字節)。我認爲問題在於我將字節數組壓縮爲100字節的方式,但我不知道提前將會有多大的壓縮數據。我在這裏做錯了什麼?我該如何解決它?

+0

使用'resultLength'作爲[文檔】(http://docs.oracle.com/javase/7/docs/api/java/util/zip/Deflater.html)一樣。 – zapl

+0

@zapl在壓縮完成後給出壓縮數據的長度。我需要在初始化之前初始化輸出數組,否則我得到一個錯誤:'變量壓縮可能沒有被初始化' – yasar

+0

@HighPerformanceMark我不知道如何檢查。我在Windows 7(64位) – yasar

回答

1

如果你不想寫全陣列,而是寫只是被Deflater使用充滿OutputStream#write(byte[] array, int offset, int lenght)

大致是

String input = "yasar\0yasar"; // test input. Input will have null character in it. 
byte[] compressed = new byte[100]; // hold compressed content 

Deflater compresser = new Deflater(); 
compresser.setInput(input.getBytes()); 
compresser.finish(); 
int length = compresser.deflate(compressed); 
File test_file = new File(System.getProperty("user.dir"), "test_file"); 
try { 
    if (!test_file.exists()) { 
     test_file.createNewFile(); 
    } 
    try (FileOutputStream fos = new FileOutputStream(test_file)) { 
     fos.write(compressed, 0, length); // starting at 0th byte - lenght(-1) 
    } 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

你仍然可能會看到1kB或它的一部分所以在Windows中,因爲您看到的內容似乎是四捨五入的(您之前寫入了100個字節),或者它指的是文件系統上的大小至少爲1 block較大(應爲4kb IIRC)。右鍵單擊文件並檢查屬性中的大小,它應顯示實際大小。


如果你不事先知道大小,不使用Deflater,使用DeflaterOutputStream是壓縮任意長度的寫入數據。

try (OutputStream out = new DeflaterOutputStream(new FileOutputStream(test_file))) { 
    out.write("hello!".getBytes()); 
} 

上面的例子將使用默認值,放氣,但你可以在DeflaterOutputStream構造函數傳遞一個配置Deflater去改變。

+0

接受第一部分,+1輸出流;) – yasar

+0

流通常更容易使用,並且可以將它們連接在一起,例如,寫數據首先被加密,然後被壓縮,然後可能只是通過將數據流封裝在數據流中而進行編碼。 – zapl

0

您要寫入的文件爲compressed數組的所有100個字節,但您只需寫出deflater返回的真正壓縮的字節。 int compressedsize = compresser.deflate(compressed);
fos.write(compressed, 0, compressedsize);