HTTP PUTで受信した受信データストリームを圧縮するためにjava.util.zip.Deflaterを使用しています。つまり、データを取得します。廊下や裸足で圧縮するのではなく、一気に圧縮する。だから私のHTTPリクエストハンドラを繰り返し、データが入って来て、このように見えるメソッドを呼び出します。 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リクエストから受信された場合、crc
とbyteCount
インスタンス変数からCRCと合計非圧縮長を追加します。
compress
メソッドが一度しか呼び出されないため、HTTP PUTで非常に少量のデータを送信する限り、これは素晴らしい結果をもたらします。私は有効なgzipファイルで終わる。私がthis.compressor.setInput(input)
を呼び出したにもかかわらず、compress
が複数回呼び出されると、すぐに私はcompress
が複数回呼び出され、それが機能しません。compress
の最初の呼び出し以降、this.compressor.finished()
がtrueを返します。新しい入力データすべてのデータが処理された後に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に書き込まれます。入力ストリームまたは出力ストリームはありません。 –