6

次のコードは、java.util.zip.Deflaterのjavadocsに記載されている例に基づいています。私が行った唯一の変更は、dictというバイト配列を作成し、setDictionary(byte [])メソッドを使用してDeflaterインスタンスとInflaterインスタンスの両方にディクショナリを設定することです。

私が見ている問題は、Deflaterに使用したものとまったく同じ配列でInflater.setDictionary()を呼び出すと、IllegalArgumentExceptionが発生することです。

問題のコードは次のとおりです。

import java.util.zip.Deflater;
import java.util.zip.Inflater;

public class DeflateWithDictionary {
    public static void main(String[] args) throws Exception {
        String inputString = "blahblahblahblahblah??";
        byte[] input = inputString.getBytes("UTF-8");
        byte[] dict = "blah".getBytes("UTF-8");

        // Compress the bytes
        byte[] output = new byte[100];
        Deflater compresser = new Deflater();
        compresser.setInput(input);
        compresser.setDictionary(dict);
        compresser.finish();
        int compressedDataLength = compresser.deflate(output);

        // Decompress the bytes
        Inflater decompresser = new Inflater();
        decompresser.setInput(output, 0, compressedDataLength);
        decompresser.setDictionary(dict);  //IllegalArgumentExeption thrown here
        byte[] result = new byte[100];
        int resultLength = decompresser.inflate(result);
        decompresser.end();

        // Decode the bytes into a String
        String outputString = new String(result, 0, resultLength, "UTF-8");
        System.out.println("Decompressed String: " + outputString);
    }
}

辞書を設定せずに同じ圧縮バイトをデフレートしようとすると、エラーは発生しませんが、返される結果はゼロバイトです。

Deflater / Inflaterでカスタム辞書を使用するために特別なことはありますか?

4

1 に答える 1

10

私は実際に質問を作成しているときにこれを理解しましたが、他の人が私の苦労から利益を得ることができるように、とにかく質問を投稿する必要があると思いました。

入力を設定した後、辞書を設定する前に、inflate()を1回呼び出す必要があることがわかりました。返される値は0になり、needsDictionary()を呼び出すとtrueが返されます。その後、辞書を設定して、もう一度inflateを呼び出すことができます。

修正されたコードは次のとおりです。

import java.util.zip.Deflater;
import java.util.zip.Inflater;

public class DeflateWithDictionary {
    public static void main(String[] args) throws Exception {
        String inputString = "blahblahblahblahblah??";
        byte[] input = inputString.getBytes("UTF-8");
        byte[] dict = "blah".getBytes("UTF-8");

        // Compress the bytes
        byte[] output = new byte[100];
        Deflater compresser = new Deflater();
        compresser.setInput(input);
        compresser.setDictionary(dict);
        compresser.finish();
        int compressedDataLength = compresser.deflate(output);

        // Decompress the bytes
        Inflater decompresser = new Inflater();
        decompresser.setInput(output, 0, compressedDataLength);
        byte[] result = new byte[100];
        decompresser.inflate(result);
        decompresser.setDictionary(dict);
        int resultLength = decompresser.inflate(result);
        decompresser.end();

        // Decode the bytes into a String
        String outputString = new String(result, 0, resultLength, "UTF-8");
        System.out.println("Decompressed String: " + outputString);
    }
}

これは、API設計の観点からは非常に直感的で扱いにくいように思われるので、より良い代替案があれば教えてください。

于 2011-04-13T21:22:02.497 に答える