【问题标题】:What's wrong with this use of java Deflater/Inflater with a dictionary将 java Deflater/Inflater 与字典一起使用有什么问题
【发布时间】:2015-02-04 03:13:31
【问题描述】:

我正在尝试将InflaterDeflater 与字典一起使用,但它不起作用。当我运行这个简单的测试程序时:

import java.io.*;
import java.util.*;
import java.util.zip.*;

public class DictTest {

    public static void main(String[] args) throws Exception {

        final int level = 9;
        final boolean nowrap = true;

        // compress
        final Deflater def = new Deflater(level, nowrap);
        final byte[] abcd = new byte[] { 0x41, 0x42, 0x43, 0x44 };
        def.setDictionary(abcd);
        def.setInput(abcd);
        def.finish();
        final byte[] buf = new byte[1024];
        final int nbytes = def.deflate(buf);
        assert def.finished();
        def.end();

        // decompress
        final Inflater inf = new Inflater(nowrap);
        inf.setInput(buf, 0, nbytes + 1);       // include extra "dummy" byte
        while (true) {
            while (inf.inflate(buf) != 0) {
                // discard
            }
            assert !inf.needsInput();
            if (inf.finished())
                break;
            assert inf.needsDictionary();
            inf.setDictionary(abcd);
            continue;
        }
        inf.end();
    }
}

我得到了这个例外:

$ javac DictTest.java && java -ea DictTest
Exception in thread "main" java.util.zip.DataFormatException: invalid distance too far back
    at java.util.zip.Inflater.inflateBytes(Native Method)
    at java.util.zip.Inflater.inflate(Inflater.java:259)
    at java.util.zip.Inflater.inflate(Inflater.java:280)
    at DictTest.main(DictTest.java:27)

我做错了什么?谢谢。

【问题讨论】:

  • 我没有使用流 - 我直接使用 Deflater/Inflater,因为这是使用字典所必需的。 ZIP 和 GZIP 都基于相同的 zlib 'deflate' 算法,它是 LZ77 的变体。见en.wikipedia.org/wiki/Zlib#Algorithm

标签: java zlib


【解决方案1】:

在设置输入之前设置充气器字典。此外,您的无限循环将(永远)运行。你想要类似的东西

final int level = 9;
final boolean nowrap = true;

// compress
final Deflater def = new Deflater(level, nowrap);
final byte[] abcd = new byte[] { 0x41, 0x42, 0x43, 0x44 };
def.setDictionary(abcd);
def.setInput(abcd);
def.finish();
final byte[] buf = new byte[1024];
final int nbytes = def.deflate(buf);
assert def.finished();
def.end();

// decompress
final Inflater inf = new Inflater(nowrap);
inf.setDictionary(abcd);
inf.setInput(buf); // include extra "dummy" byte
while (inf.inflate(buf) != 0) {
    // discard
}
assert !inf.needsInput();
assert inf.needsDictionary();
inf.end();

然后它在这里运行而没有错误。

【讨论】:

  • 谢谢,但这很奇怪。根据stackoverflow.com/questions/5655740/…,您必须在调用 inflate() 并返回 needsDictionary() == true 后设置字典。
  • 您使用的是静态字典。阅读该链接答案中的评论。
  • 我还是不明白。为什么在原始代码中,inflate() 会抛出异常而不是返回零并请求字典(通过 needsDictionary() 返回 true)?换句话说,假设解压缩代码事先不知道是否有任何字典用于压缩,或者如果是,是哪一个。那你会怎么写解压代码来处理所有可能的情况呢?
猜你喜欢
  • 2011-08-05
  • 1970-01-01
  • 2018-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多