我使用java.util.zip.Deflater來壓縮通過HTTP PUT接收的數據流,這意味着我得到的數據用點滴和單調壓縮,不是一次全部壓縮。 調用java.util.zip.Deflater.setInput多次在第一次之後什麼也不做
byte[] compress(byte[] input) {
byte[] output = null;
if (this.compressor == null) {
this.compressor = new Deflater(Deflater.BEST_COMPRESSION, true);
// Add gzip header:
output = getGzipHeader();
}
this.compressor.setInput(input);
this.compressor.finish();
while (!this.compressor.finished()) {
byte[] tempOutput = new byte[10240];
int compressedLength = this.compressor.deflate(tempOutput);
if (output == null) {
output = Arrays.copyOf(tempOutput, compressedLength);
} else {
byte[] newOutput = Arrays.copyOf(output, output.length + compressedLength);
System.arraycopy(tempOutput, 0, newOutput, output.length, compressedLength);
output = newOutput;
}
}
// Update CRC:
this.crc.update(input);
this.byteCount += input.length;
return output
}
當然包含此方法的類有實例變量:
private Deflater compressor;
private CRC32 crc = new CRC32();
private long byteCount = 0;
而且一旦這樣的數據來自於我的HTTP請求處理程序反覆調用,看起來像這樣的方法從HTTP請求收到最後一個字節,我附加CRC和來自crc
和byteCount
實例變量的總未壓縮長度。
只要我在HTTP PUT中發送非常少量的數據,這個工作很好,因爲compress
方法只被調用一次。我結束了一個有效的gzip文件。只要我發送超過幾百字節,導致compress
不止一次被調用,它不起作用,因爲在第一次調用後所有後續調用compress
,this.compressor.finished()
返回true,即使我調用this.compressor.setInput(input)
與新的輸入數據。如果在處理完所有數據後查看this.compressor.getBytesRead()
,則該調用返回的值恰好是第一個輸入緩衝區的大小(第一個調用this.compressor.setInput(input)
)。對該方法的後續調用都不會增加由getBytesRead()
返回的值。
如果我在撥打setInput()
後沒有撥打finish()
,它根本不起作用 - 我沒有輸出。但好像打電話finish()
是告訴Deflater
不接受任何多輸入。
我在做什麼錯?
做這個幫助:[DeflaterOutputStream](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/zip/DeflaterOutputStream.java#119 )? (並且直接使用這個類會有意義嗎?) – jtahlborn
正如jtahlborn所說,DeflaterOutputStream會大大地幫助。作爲一般性評論,如果您使用'ArrayList.addAll(Arrays.asList(tempOutput))'而不是自己完成所有數組操作,那麼您的代碼看起來會更簡單。 –
@jtahlborn,不,據我所知,沒有辦法讓我使用DeflatorOutputStream,因爲我沒有輸出流寫入。我可能應該提到我的服務是使用[Vert.x](http://vertx.io)構建的,所以我正在從[ReadStream](http://vertx.io/docs/apidocs/index .html?io/vertx/core/streams/ReadStream.html)並寫入[AsyncFile](http://vertx.io/docs/apidocs/index.html?io/vertx/core/file/AsyncFile.html )。數據從字節緩衝區中的ReadStream接收並寫入字節緩衝區中的AsyncFile。沒有輸入或輸出流。 –