3

編集:Deflater派生クラスがヘッダーとフッターのデータを書き込むことを決定したとき、およびそれらの事実を活用する方法を知る必要があります。私は本当に次のことをしたいと思います:

  1. Deflater派生クラスの辞書をいくつかのバイトでプライミングします(私はこれを取得したと思います)。

  2. 圧縮するデータをDeflater派生クラスに送信します(これを取得したと思います)。

  3. その圧縮されたすべてのデータ(ヘッダーまたはフッターデータなし)を必要な場所に出力します(これを行う方法がわからない場合は、ヘッダー/フッターの両方、または1つだけを使用しても問題ありません)。 。

  4. 1からやり直して、オブジェクトを再利用します。

元のQ:JavaDeflaterOutputStreamを使用して一部のデータを圧縮しています。また、ヘッダーとフッターを変更して、この圧縮データを変更しています。DeflaterOutputStreamに入力を与え、gzip形式のヘッダーやフッターではなく、圧縮されたデータ部分のみを出力するようにします。どうすればこれを行うことができますか?

これまでのところ、私はこのようなことをしようとしてきました:

internalWriter.write(storage, 0, amountRead);
internalWriter.finish();
internalWriter.getDef().reset();

ここでのinternalWriterは、DeflaterOutputStreamの拡張です。これにより、圧縮データがヘッダーとフッターとともに出力されます。ただし、同じオブジェクトを使用した後続の呼び出しでは、圧縮されたデータとフッターが出力されます。基本的には、圧縮されたデータのみ、またはおそらく毎回同じことが発生するようにしたいです。何か案は?圧縮ストリームがclose、flush、finishをどのように使用するかについての簡単な説明は、ヘッダーとフッターがいつ作成および出力されるかに焦点を当てて、私にも役立つかもしれません。

そして、DeflaterOutputStreamを使用するたびに、すべてをすぐに出力したいと思っています。そういうわけで、私は上記のように右の直後にフィニッシュをしました...

4

3 に答える 3

3

Java Almanacで良い例を見ることができます

- - 編集 - -

もう少しお手伝いさせてください。Elliote Rusty Harold による本Java I/Oは、おそらく私が見つけた最良のリファレンスです。OReilly Books から入手できます。本からの引用と例をいくつか紹介します。

データの収縮

Deflater クラスには、データのブロックを圧縮するためのメソッドが含まれています。圧縮形式、圧縮レベル、および圧縮方法を選択できます。Deflater クラスを使用してデータをデフレートするには、次の 9 つの手順が必要です。

  1. Deflater オブジェクトを構築します。
  2. 戦略を選択します (オプション)。
  3. 圧縮レベルを設定します (オプション)。
  4. 辞書をプリセットします (オプション)。
  5. 入力を設定します。
  6. needsInput( ) が true を返すまで、繰り返しデータを収縮させます。
  7. さらに入力できる場合は、ステップ 5 に戻って追加の入力データを提供します。それ以外の場合は、手順 8 に進みます。
  8. データを仕上げます。
  9. デフレートするストリームがさらにある場合は、デフレーターをリセットします。

多くの場合、このクラスを直接使用することはありません。代わりに、DeflaterInputStream や DeflaterOutputStream などの圧縮ストリーム クラスの 1 つを介して間接的に Deflater オブジェクトを使用します。これらのクラスは、未加工の Deflater メソッドよりも便利なストリーム指向圧縮用のプログラマ インターフェイスを提供します。

データの膨張

  1. Inflater オブジェクトを構築します。
  2. 圧縮データをインフレートする入力を設定します。
  3. あらかじめ設定された辞書が必要かどうかを判断するには、needsDictionary( ) を呼び出します。
  4. needsDictionary( ) が true を返した場合は、getAdler( ) を呼び出して辞書の Adler-32 チェックサムを取得します。次に、setDictionary( ) を呼び出して辞書データを設定します。
  5. inflate( ) が 0 を返すまで繰り返しデータを膨張させます。
  6. needsInput( ) が true を返した場合は、手順 2 に戻って追加の入力データを提供します。
  7. finished( ) メソッドは true を返します。

さて、この本はデータの圧縮と圧縮解除に 1 つの章を割いており、ここですべてを説明することはできないと思います。タスクの一部を実行する必要があり、必要に応じて、より狭い質問で戻ってきます。

于 2012-10-24T23:51:53.250 に答える
2

デフレーター(sic)のドキュメントを参照してください。が true の場合nowrap、ヘッダーやトレーラーは生成されず、deflate 形式の生の圧縮データのみが生成されます。

于 2012-10-25T02:53:57.037 に答える
1

目的のストリームと、目的のストリームを装飾するコンプレッサー ストリームの 2 つのストリームが必要なようです。次に、非圧縮データをベース ストリームに書き込み、圧縮データをデコレータ ストリームに書き込みます。切り替える前に、必ずフラッシングを行ってください。読み取りも同様の手順になりますが、圧縮されたデータがストリームのどこで始まりどこで終わるかを知る必要があります。

宛先ストリームが次の疑似コードのようなファイルであるとします...

    FileOutputStream dest = new FileOutputStream(foo);
    DeflaterOutputStream decorator = new DeflaterOutputStream(dest);

    byte[] header = getHeader();
    byte[] body = getBody();
    byte[] footer = getFooter();

    dest.write(header);
    dest.flush();
    decorator.write(body);
    decorator.flush();
    dest.write(footer);

DeflaterOutputStreamは本当にあなたが望むものなのだろうか。それはzipファイルの一部ではありませんか?何かカスタムをしている場合は、gzip したいだけのようです。

于 2012-10-25T01:42:53.817 に答える