以下代码基于javadocs for java.util.zip.Deflater中给出的示例。我所做的唯一更改是创建一个名为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的自定义词典,我需要做些什么特别的事情吗?
答案 0 :(得分:8)
我在制定问题的过程中确实想到了这一点,但我认为我应该发布这个问题,以便其他人可以从我的挣扎中受益。
事实证明,您必须在设置输入后调用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设计的角度来看,这似乎非常直观和笨拙,所以如果有更好的选择,请赐教。