0

zlibに投稿された gzip コードのアイデアを使用しています。初期化には を使用しますdeflateInit2(p_strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY)。ストリームを圧縮しています。Z_FULL_FLUSH私が使用する最後のものを除いて、各パケットにはZ_FINISH. 各パケットを圧縮した後、パケットを並べ替えています。

パケット内のデータ ---> [zip] ---> [並べ替え] ---> ...

zip の後にデータを膨らませると、zip する前に正確なファイルを取得できます。Z_FULL_FLUSHパケットの並べ替え後にデータを膨張させると (繰り返しますが、最後の を除いて、各パケットは で収縮されZ_FINISHます)、圧縮前の元のファイルと非常によく似たファイルが得られます。違いはファイルの最後にあります。バイトが不足しています。これは、膨らませているときに最後のパケットでエラーが発生するためです ( Z_DATA_ERROR)。たとえば、50KB のチャンクで膨張させた場合、並べ替え後の膨張したファイルは入力と同じファイルであり、50KB 未満です (最後のパケット全体がエラーの原因になります)。膨張するチャンク サイズを 8B に減らしてもZ_DATA_ERROR.

最後のパケット ( Z_FINISH) を並べ替えていません。すべてのパケットを送信してZ_FULL_FLUSHから、別の「空の」パケット ( Z_FINISH10 バイトのみ) を送信しようとしました。

なぜこうなった?Z_FULL_FLUSH を使用すると、インフレータが正しく膨らませられないのはなぜですか? 収縮したパケットの順序を覚えていますか?

どんな情報でも役に立ちます、ありがとう。

4

2 に答える 2

3

Z_FULL_FLUSHフラッシュごとに履歴を消去する which を使用しているため、最後のパケットを除いて、パケットを並べ替えることができます。あなたがしたものは最後のパケットZ_FINISHなければなりません。ただし、データを持つ必要はありません。を使用して最後のパケットからすべてのデータを供給しZ_FULL_FLUSH、入力データなしで 1 つの最終パケットを実行できますZ_FINISH。これにより、空のパケットの前に好きなようにパケットを並べ替えることができます。常に最後のものを最後に持ってください。

その理由は、deflate 形式が自己終了するため、最後のピースがストリームの終わりを示すためです。どこかの真ん中に並べ替えると、そのパケットに当たったときにインフレが停止します。

gzip ヘッダーとトレーラーは最初と最後で維持する必要があり、それに応じてトレーラーの CRC が更新されます。最後の CRC チェックは、データの順序によって異なります。

やりたいことをやろうとするのはなぜ?何を最適化していますか?

于 2013-10-30T04:52:04.690 に答える
1

GZip はストリーミング プロトコルです。圧縮は、ストリームの以前の履歴に依存します。再注文することはできません。

于 2013-10-30T01:06:45.823 に答える