4

我正在尝试解压缩使用 Jean-loup Gailly 在 1990 年代编写的 ZLIB 库压缩的数据。我认为它是一个流行的库(我看到很多程序都提供它使用的 zlib32.dll 文件)所以我希望有人对它足够熟悉以帮助我。我直接使用 compress() 函数,从我读到的内容使用 rfc-1951 DEFLATE 格式。

这是我用来从流中读取一些压缩数据并解压缩的代码段:

InputStream is = new ByteArrayInputStream(buf);

//GZIPInputStream gzis = new GZIPInputStream(is);

InflaterInputStream iis = new InflaterInputStream(is);

byte[] buf2 = new byte[uncompressedDataLength];

iis.read(buf2);

iis.read(buf2) 函数引发“数据格式错误”的内部异常。我也尝试使用 GZIPInputStream ,但这也会引发相同的异常。

“buf”变量是 byte[] 类型,我通过调试确认它与我的 C 程序从 ZLIB compress() 函数返回的相同(实际数据来自 TCP 上的服务器)。“uncompressedDataLength”是由 C 程序(服务器)提供的未压缩数据的已知大小。

有没有人尝试过使用这个库读取/写入数据,然后使用 Java 在 Android 上读取/写入相同的数据?

我确实在一些地方找到了“ZLIB 的纯 Java 端口”,如果需要,我可以尝试,但如果可能的话,我宁愿使用内置/OS 函数。

4

1 回答 1

7

这里使用的数据格式deflatezlibgzip都是相关的。

  • 基础是RFC 1951中定义的deflate压缩数据格式。由于它的纯粹形式通常毫无用处,因此我们通常在它周围使用包装格式。

  • gzip压缩数据格式 ( RFC 1952 ) 用于压缩文件。它由一个包含文件名和一些属性空间的标题、一个放气数据流和一个 CRC-32 校验和(4 个字节)组成。(规范中还支持一个流中的多个此类文件,但我认为这并不经常使用。)

  • zlib压缩数据格式,在RFC 1950中定义:它由较小的标头(2 或 6 个字节)、放气数据流和末尾的 Adler-32 校验和(4 个字节)组成。(Adler-32 校验和旨在比 gzip 中使用的 CRC-32 校验和更快地计算。)它旨在用于某些其他协议内的数据压缩传输,或其他文件格式内的压缩存储。例如,它在 PNG 文件格式中使用。

zlib 库支持所有这些格式。Java 的 java.util.zip 建立在 zlib 之上(作为 VM 的实现/本机调用的一部分),并通过几个类公开对这些的访问:

  • Deflater 和 Inflater 类实现 - 根据nowrap构造函数的参数 - zlibdeflate数据格式。

  • DeflaterOutputStream/DeflaterInputStream/InflaterInputStream/InflaterOutputStream 建立在 Deflater/Inflater 之上。文档没有明确说明默认的 Inflater/Deflater 是实现zlib还是deflate,但源显示它使用实现zlibDeflater的默认值或Inflater构造函数。

  • 顾名思义,GZipOutputStream/GZipInputStream 实现了gzip格式。

看了一下zlib的函数源码compress,好像是用的zlib格式。所以你的代码应该做正确的事情。确保没有丢失的数据,或在压缩数据块之前或之后不属于压缩数据块的附加数据。

免责声明:这是 Java SE 的状态,我想它与 Android 类似,但我不能保证这一点。

您找到的jzlib库(我想)是 zlib 的 Java 重新实现,也实现了所有这些数据格式(gzip 已在最新更新中添加)。对于交互式使用(在压缩方面),它是可取的,因为它允许一些使用 java.util 的类不可能的刷新操作(除了使用一些变通方法,如更改压缩级别),而且它也可能更快,因为它避免了本机调用(总是有一些开销)。

PS:zip(或 pkzip)文件格式也相关:它在内部对存档中的每个文件使用 deflate。

于 2011-11-12T17:14:30.710 回答