標準入力からデータのストリームを取得し、一度に 128 バイト ブロックずつ圧縮してから、標準出力に出力しようとしています。(例: "cat file.txt | java Dict | gzip -d | cmp file.txt"。ここで、file.txt には ASCII 文字が含まれているだけです。)
また、後続の各ブロックに対して、前の 128 バイト ブロックの末尾から取得した 32 バイトの辞書を使用する必要があります。(最初のブロックは、独自の最初の 32 バイトを辞書として使用します。) 辞書をまったく設定しない場合、圧縮は正常に機能します。ただし、ディクショナリを設定すると、gzip でデータを解凍しようとすると、「gzip: stdin: 無効な圧縮データ--crc エラー」というエラーが表示されます。
コードのいくつかの部分を追加/変更しようとしましたが、これまで何も機能せず、Google で解決策を見つけることができませんでした。
私はもう試した...
- コードの下部にある「def.setDictionary(b)」の前に「def.reset()」を追加しても機能しません。
- 最初のブロックの後のブロックの辞書を設定するだけでは機能しません。(最初のブロックには辞書を使用しません。)
- compression.write(input, 0, bytesRead) の前後に「input」配列を指定して updateCRC を呼び出しても機能しません。
何か提案をいただければ幸いです - 私が見逃している、または間違っていることが明らかなことはありますか?
これは私の Dict.java ファイルにあるものです:
import java.io.*;
import java.util.zip.GZIPOutputStream;
public class Dict {
protected static final int BLOCK_SIZE = 128;
protected static final int DICT_SIZE = 32;
public static void main(String[] args) {
InputStream stdinBytes = System.in;
byte[] input = new byte[BLOCK_SIZE];
byte[] dict = new byte[DICT_SIZE];
int bytesRead = 0;
try {
DictGZIPOuputStream compressor = new DictGZIPOuputStream(System.out);
bytesRead = stdinBytes.read(input, 0, BLOCK_SIZE);
if (bytesRead >= DICT_SIZE) {
System.arraycopy(input, 0, dict, 0, DICT_SIZE);
compressor.setDictionary(dict);
}
do {
compressor.write(input, 0, bytesRead);
compressor.flush();
if (bytesRead == BLOCK_SIZE) {
System.arraycopy(input, BLOCK_SIZE-DICT_SIZE-1, dict, 0, DICT_SIZE);
compressor.setDictionary(dict);
}
bytesRead = stdinBytes.read(input, 0, BLOCK_SIZE);
} while (bytesRead > 0);
compressor.finish();
}
catch (IOException e) {e.printStackTrace();}
}
public static class DictGZIPOuputStream extends GZIPOutputStream {
public DictGZIPOuputStream(OutputStream out) throws IOException {
super(out);
}
public void setDictionary(byte[] b) {
def.setDictionary(b);
}
public void updateCRC(byte[] input) {
crc.update(input);
}
}
}