非常に単純なものが欠けていると思います。デフレーターを使用して書き込まれたデフレートされたデータを保持するバイト配列があります。
deflate(outData, 0, BLOCK_SIZE, SYNC_FLUSH)
GZIPOutputStream を使用しなかった理由は、それぞれにデータ ブロックが与えられた 4 つのスレッド (変数) があり、各スレッドが独自のブロックを圧縮してから、その圧縮データをグローバル バイト配列に格納したためです。GZIPOutputStream を使用すると、各小さなブロックにヘッダーとトレーラーがあり、それが独自の gzip データであるため、形式が台無しになります (圧縮したいだけです)。
最終的に、すべての圧縮データを保持するこの byteArray である outData を取得しましたが、それをラップする方法がよくわかりません。GZIPOutputStream は圧縮されていないデータをバッファから書き込みますが、この配列はすべて設定されています。すでに圧縮されており、それを形にする方法を見つけようとして壁にぶつかっています。
編集:わかりました、私の側の悪い言葉遣い。必要に応じてリダイレクトできるように、ファイルではなく出力に書き込んでいます。本当に簡単な例は、
cat file.txt | java Jzip | gzip -d | cmp file.txt
0を返す必要があります。現在の問題は、このバイト配列をそのまま出力する場合、それは単なる「生の」圧縮データであることです。gzip には、このすべての追加情報が必要だと思います。
別の方法があれば、それで問題ありません。このような理由は、複数のスレッドを使用する必要があったためです。それ以外の場合は、GZIPOutputStream を呼び出すだけです。
ダブル編集: コメントは多くの優れた洞察を提供するため、別の方法は、もともと 1 つの長いストリームであった圧縮されていないデータのブロックをたくさん持っていることです。gzip が連結されたストリームを読み取ることができる場合、それらのブロックを取得し (そしてそれらを順番に保持し)、それぞれを独自のブロックで GZIPOutputStream を呼び出すスレッドに渡した場合、結果を取得してそれらを連結しました。基本的に、各ブロックにはヘッダー、圧縮された情報、およびトレーラーがあります。それらを連結した場合、gzipはそれを認識しますか?
例:
cat file.txt
Hello world! How are you? I'm ready to set fire to this assignment.
java Testcase < file.txt > file.txt.gz
だから私は入力からそれを受け入れます。プログラム内で、ストリームは「Hello world!」に分割されます。"大丈夫?" 「この割り当てに火をつける準備ができました」 (文字列ではなく、単なるバイトの配列です! これは単なる説明です)
つまり、これら 3 つのバイト ブロックがあり、すべて圧縮されていません。これらの各ブロックをスレッドに渡します。
public static class DGZIPOutputStream extends GZIPOutputStream
{
public DGZIPOutputStream(OutputStream out, boolean flush) throws IOException
{
super(out, flush);
}
public void setDictionary(byte[] b)
{
def.setDictionary(b);
}
public void updateCRC(byte[] input)
{
crc.update(input);
}
}
ご覧のとおり、ここではフラッシュを SYNC_FLUSH に設定しただけなので、整列を正しく行い、ディクショナリを設定することができます。各スレッドが DGZIPOutputStream (これはテスト済みで、1 つの長い連続入力に対して機能します) を使用し、これら 3 つのブロック (現在はヘッダーとトレーラーでそれぞれ圧縮されています) を連結すると、 gzip -d file.txt.gz が機能します。 ?
それが奇妙すぎる場合は、辞書を完全に無視してください。それは本当に問題ではありません。途中で追加しただけです。