deflateroutputstreamのdeflate()をいつ使用するのですか?

Dec 23 2020

冬休みの時間をつぶすためにdeflateroutputstreamを使用する方法を学ぼうとしています。ドキュメントを見ると、混乱しています。https://docs.oracle.com/javase/7/docs/api/java/util/zip/DeflaterOutputStream.html、deflate()は圧縮データをoutputstreamに書き込むために使用され、write()はデータをdeflateroutputstream(圧縮されたoutputstream)に書き込んで圧縮されることを示しています。

しかし、私はインターネットでサンプルコードを見ていますが、誰もdeflate()を使用していません。これまでに見たすべてのコードは、deflate()を呼び出さずにdeflateroutputstreamにwrite()するだけです。https://stackoverflow.com/a/13060441/12181863
https://www.programcreek.com/java-api-examples/?api=java.util.zip.DeflaterOutputStream

コードがfileoutputstreamをdeflateroutputstream内に配置していることに気付きましたが、どのように相互作用しますか?データがdeflateroutputstreamに書き込まれるときに、圧縮されたデータをfileoutputstreamに送信するために自動的にdeflate()を呼び出しますか?

回答

3 rzwitserloot Dec 23 2020 at 21:21

それprotectedは:それはそのストリームをサブクラス化するものすべてを対象としており、あなたがそれをサブクラス化するのではありません。あなたに関する限り、それはあなたの推論に含めることができない実装の詳細であり、あなたが呼び出すことを意図していません。

もちろん、サブクラス化しない限り。

どちらが可能か-それは、LZベースの圧縮ストリームをその上に構築するための一種のツールキットです。これが、GZipOutputStreamとZipOutputStreamの両方がそれを拡張する理由です。これらは、多かれ少なかれ同じ圧縮テクノロジーを使用する異なるコンテナーです。そして、彼らはそれを呼び出しdeflateます。独自のLZベースの圧縮システムを開発している場合、または既存の非zip、非gz、非デフレーターベースの圧縮形式用のリーダーを実装している場合を除き、これはユーザー向けではありません。

これらの種類の出力ストリームは「フィルターストリーム」と呼ばれます。それら自体はリソースを表すものではなく、リソースをラップアラウンドします。それらは任意のものをラップアラウンドできOutputStream(または任意のInputStream、概念は「両側」で機能します)、転送中のバイトを変更できます。

var out = new DeflaterOutputStream(whatever)(を介してout.write(stuff))送信したデータを圧縮する新しいデフレータストリームを作成し、圧縮されたデータを取得して何にでも送信します。それは次の仕事をします:

  1. (に従ってout.write)バイトを取り、ジョブを実行するために必要なだけバッファリングします。
  2. ...このデータを圧縮します。
  3. 次に、圧縮されたデータを、whateverそのwriteメソッドを呼び出して、ラップされた出力ストリーム(この例では)に送信することにより、圧縮されたときに処理します。

基本的な使用法は次のとおりです。

  1. Files.newOutputStreamor、someSocket.getOutputStreamor httpServletResponse.getOutputStream()System.outまたはストリームを生成するその他のリソースを作成します。これは、物事を柔軟にするという理由から抽象的な概念です。
  2. そのリソースをにラップします DeflaterOutputStream
  3. すべてのデータをdeflateroutputstreamに書き込みます。オリジナルのことは忘れてください。DeflaterOutputStreamに渡すことができるように作成しました。これで、基になるストリームとの対話が終了します。
  4. デフレータストリームを閉じます(これにより、基になるストリームも閉じられます)。