Использование Java Deflater / Inflater с пользовательским словарем вызывает IllegalArgumentException - PullRequest
6 голосов
/ 14 апреля 2011

Следующий код основан на примере, приведенном в javadocs для java.util.zip.Deflater . Единственные изменения, которые я сделал, - это создание байтового массива с именем dict, а затем установка словаря для экземпляров Deflater и Inflater с использованием метода setDictionary (byte []).

Проблема, с которой я сталкиваюсь, заключается в том, что когда я вызываю Inflater.setDictionary () с точно таким же массивом, который я использовал для Deflater, я получаю исключение 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?

1 Ответ

8 голосов
/ 14 апреля 2011

Я на самом деле понял это при формулировании вопроса, но подумал, что должен в любом случае опубликовать вопрос, чтобы другие могли извлечь выгоду из моей борьбы.

Оказывается, вы должны вызывать inflate () один раз после настройки входа, но до установки словаря. Возвращаемое значение будет равно 0, и тогда при вызове needsDictionary () будет возвращено значение true. После этого вы можете установить словарь и снова вызвать инфляцию.

Измененный код выглядит следующим образом:

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, поэтому, пожалуйста, сообщите мне, если есть какие-либо более лучшие альтернативы.

...