使用带有自定义字典的Java Deflater / Inflater会导致IllegalArgumentException [英] Using Java Deflater/Inflater with custom dictionary causes IllegalArgumentException

查看:214
本文介绍了使用带有自定义字典的Java Deflater / Inflater会导致IllegalArgumentException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码基于 java.util.zip.Deflater的javadocs 。我所做的唯一的更改是创建一个名为dict的字节数组,然后使用setDictionary(byte [])方法在Deflater和Inflater实例上设置字典。



我看到的问题是,当我调用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);

//压缩字节
byte [] output = new byte [100];
Deflater compresser = new Deflater();
compresser.setInput(input);
compresser.setDictionary(dict);
compresser.finish();
int compressedDataLength = compresser.deflate(output);

//解压缩字节
Inflater decompresser = new Inflater();
decompresser.setInput(output,0,compressedDataLength);
decompresser.setDictionary(dict); // IllegalArgumentExeption throwwn here
byte [] result = new byte [100];
int resultLength = decompresser.inflate(result);
decompresser.end();

//将字节解码为字符串
String outputString = new String(result,0,resultLength,UTF-8);
System.out.println(Decompressed String:+ outputString);
}
}

如果我尝试减压相同的压缩字节,字典,我没有错误,但返回的结果是零字节。



有什么特别的,我需要做,为了使用Deflater / Inflater的自定义字典? / p>

解决方案

我实际上想出了这个问题,但我认为我应该发布问题,所以其他人可能从我的斗争中受益。 / p>

原因是你必须在设置输入之后调用inflate()一次,但在之前设置字典。返回的值将为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);

//压缩字节
byte [] output = new byte [100];
Deflater compresser = new Deflater();
compresser.setInput(input);
compresser.setDictionary(dict);
compresser.finish();
int compressedDataLength = compresser.deflate(output);

//解压缩字节
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();

//将字节解码为字符串
String outputString = new String(result,0,resultLength,UTF-8);
System.out.println(Decompressed String:+ outputString);
}
}

这看起来与API设计非常相反透视,所以请告诉我,如果有更好的替代品。


The following code is based on the example given in the javadocs for java.util.zip.Deflater. The only changes I have made is to create a byte array called dict and then set the dictionary on both the Deflater and Inflater instances using the setDictionary(byte[]) method.

The problem I'm seeing is that when I call Inflater.setDictionary() with the exact same array as I used for the Deflater, I get an IllegalArgumentException.

Here is the code in question:

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);
    }
}

If I try deflating the same compressed bytes without setting the dictionary, I get no error but the result returned is zero bytes.

Is there anything special I need to do in order to use a custom dictionary with Deflater/Inflater?

解决方案

I actually figured this out while formulating the question but thought I should post the question anyway so others might benefit from my struggles.

It turns out you have to call inflate() once after setting the input but before setting the dictionary. The value returned will be 0, and a call to needsDictionary() will then return true. After that you can set the dictionary and call inflate again.

The amended code is as follows:

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);
    }
}

This seems very counter intuitive and clunky from an API design perspective, so please enlighten me if there are any better alternatives.

这篇关于使用带有自定义字典的Java Deflater / Inflater会导致IllegalArgumentException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆