-1

を使用してJava Deflater (1.6 is needed)、特定のサイズの圧縮ブロック (たとえば、常に 1024 バイトの圧縮ブロック) を生成したいと考えています。出来ますか?

入力を追加して、出力バッファがいっぱいになるまで(Deflater::setInput(newData))圧縮されたバイトを取得しようとし(::deflate(buffer, startFrom, remainingBytes))ました (例: 1024)。しかし、多くの場合、他のバイトがデフレーターに残っており (たとえば、finished()false だった)、圧縮された newData のどの部分がそこにあったかを知る方法がありません。

さらに、受信側はさまざまな時点でパケットを受信でき、受信側が持つ唯一の情報は圧縮されたブロック サイズであるため、各パケットは自動整合性を保つ必要があります。

10倍

4

2 に答える 2

1

これは、反復プロセスによってのみ行うことができます。そして、正確に 1024 バイトに到達することは依然として不可能であることに気付くかもしれません。

アプローチは、1024 バイトを超えるまで最初に圧縮することです。次に、圧縮された出力の最初の 1019 バイト (またはnowraptrue の場合は最初の 1023 バイト) を取得し、データが返されなくなるまで解凍します。次に、取得したバイトのみで再度圧縮します。正確に 1024 バイトを取得する場合もあれば、非常に近い値を取得する場合もあります。出力が必要以上に小さいか大きいかに応じて、入力のバイト数を上下に調整し、再度圧縮します。反復が常に完了するように、コードを慎重に記述してください。

非圧縮バイトを 1 つ追加すると、圧縮バイトが 1023 から 1025 になる場合があります。その場合は、1023 バイトで解決する必要があります。または、別の圧縮レベルでもう一度試すこともできます。

ところで、出力を 1K に制限すると、あまり良い圧縮が得られません。適切な圧縮は、多くの履歴へのアクセスに依存します。より長い圧縮ストリームを複数の 1K パケットに分割して送信することを検討する必要があります。パケットが異なる順序で到着する場合は、圧縮解除のために相手側でパケットを適切に並べ替えるようにしてください。

于 2013-09-20T18:56:51.827 に答える
0

残念ながら、解決策は Java 7 にあります。Java 7 で syncFlush=true、DeflaterOutputStream with syncrFlushが必要です。

これによりflush()、ストリームにアクセスし、レシーバーにデータを読み取らせることができます。flush()残念なことに、ほとんどの圧縮ライブラリは、圧縮バッファをフラッシュすることを尊重していません。

于 2013-09-20T20:42:34.683 に答える