3

我正在使用 DeflaterOutputStream 将数据压缩为专有存档文件格式的一部分。然后我使用 jcraft zlib 代码在另一端解压缩该数据。另一端是 J2ME 应用程序,因此我依赖第三方 zip 解压缩代码而不是标准 Java 库。

我的问题是某些文件可以很好地压缩和解压缩,而其他文件则不能。

对于那些没有的,数据第一个字节中的压缩方法似乎是“5”。

从我对 zlib 的阅读中,我了解到默认值“8”表示默认的 deflate 压缩方法。解压器似乎无法接受任何其他值。

我想知道的是:

  • “5”代表什么?
  • 为什么 DeflaterOutputStream 有时会使用不同的压缩方法?
  • 我能以某种方式阻止它这样做吗?
  • 是否有另一种方法可以生成仅使用默认压缩方法的压缩数据?
4

1 回答 1

7

这可能有助于准确地磨练您正在查看的内容。

在整个数据之前,通常有一个两字节的ZLIB 标头。据我所知,这些第一个字节的低 4 位应始终为 8。如果你在 nowrap 模式下初始化你的 Deflater,那么你根本不会得到这两个字节(尽管你的其他库必须期望不会得到它们)。

然后,在每个单独的数据块之前,有一个3 位的块头(注意,定义为位数,而不是字节的整数)。可以想象,您可以有一个以字节 5 开头的块,这表示压缩块是最终块,或者以字节 8 开头,这将是一个未压缩的非最终块。

创建 DeflaterOutputStream 时,可以将 Deflater 或您的选择传递给构造函数,在该 Defalter 上,您可以设置一些选项。该级别本质上是压缩在查找数据中的重复模式时使用的预读量;碰巧,您可以尝试将其设置为非默认值,看看它是否对您的解压缩器是否可以应付有任何影响。

策略设置(参见 setStrategy() 方法)可以在某些特殊情况下用于告诉 deflater 仅应用霍夫曼压缩。在您已经转换数据以使值的频率接近 2 的负幂(即霍夫曼编码最适合的分布)的情况下,这有时会很有用。我不希望此设置会影响库是否可以读取您的数据,但很有可能,您可能只是尝试更改此设置。

如果它有帮助,我写了一些关于配置 Deflater的文章,包括对转换后的数据使用 Huffman-only 压缩。我必须承认,无论您选择什么选项,我都希望您的图书馆能够读取数据。如果您真的确定您的压缩数据是正确的(即 ZLIB/Inflater 可以重新读取您的文件),那么您可能会考虑使用另一个库...!

哦,说明流血很明显,但无论如何我都会提到它,如果你的数据是固定的,你当然可以把它放在罐子里,它会有效地“免费”放气/充气。具有讽刺意味的是,您的 J2ME 设备必须能够解码 zlib 压缩数据,因为这本质上是 jar 的格式......

于 2009-05-29T17:36:54.303 回答