Gzip格式文件(例如,使用 gzip 程序创建)使用"deflate"压缩算法,该算法与zlib使用的压缩算法相同 . 但是,当使用zlib来扩展gzip压缩文件时,库会返回 Z_DATA_ERROR .
gzip
Z_DATA_ERROR
如何使用zlib解压缩gzip文件?
要使用zlib解压缩gzip格式文件,请使用 windowBits 参数调用 inflateInit2 作为 16+MAX_WBITS ,如下所示:
windowBits
inflateInit2
16+MAX_WBITS
inflateInit2(&stream, 16+MAX_WBITS);
如果你不这样做,zlib会抱怨一个糟糕的流格式 . 默认情况下,zlib使用zlib标头创建流,并且在inflate中无法识别不同的gzip标头,除非您这样说 . 虽然从 zlib.h 头文件的1.2.1版开始记录了这一点,但它不在zlib manual中 . 从头文件:
zlib.h
对于可选的gzip解码,windowBits也可以大于15 . 向windowBits添加32以使用自动标头检测启用zlib和gzip解码,或添加16以仅解码gzip格式(zlib格式将返回Z_DATA_ERROR) . 如果正在解码gzip流,则strm-> adler是crc32而不是adler32 .
zlib library supports:
RFC 1950( zlib 压缩格式)
zlib
RFC 1951( deflate 压缩格式)
deflate
RFC 1952( gzip 压缩格式)
python zlib 模块也将支持这些 .
但 zlib 可以解压缩所有这些格式:
到(de-)压缩 deflate 格式,使用 wbits = -zlib.MAX_WBITS
wbits = -zlib.MAX_WBITS
到(de-)压缩 zlib 格式,使用 wbits = zlib.MAX_WBITS
wbits = zlib.MAX_WBITS
到(de-)压缩 gzip 格式,使用 wbits = zlib.MAX_WBITS | 16
wbits = zlib.MAX_WBITS | 16
请参阅http://www.zlib.net/manual.html#Advanced中的文档(第 inflateInit2 节)
测试数据:
>>> deflate_compress = zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS) >>> zlib_compress = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS) >>> gzip_compress = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS | 16) >>> >>> text = '''test''' >>> deflate_data = deflate_compress.compress(text) + deflate_compress.flush() >>> zlib_data = zlib_compress.compress(text) + zlib_compress.flush() >>> gzip_data = gzip_compress.compress(text) + gzip_compress.flush() >>>
zlib 的明显测试:
>>> zlib.decompress(zlib_data) 'test'
测试 deflate :
>>> zlib.decompress(deflate_data) Traceback (most recent call last): File "<stdin>", line 1, in <module> zlib.error: Error -3 while decompressing data: incorrect header check >>> zlib.decompress(deflate_data, -zlib.MAX_WBITS) 'test'
测试 gzip :
>>> zlib.decompress(gzip_data) Traceback (most recent call last): File "<stdin>", line 1, in <module> zlib.error: Error -3 while decompressing data: incorrect header check >>> zlib.decompress(gzip_data, zlib.MAX_WBITS|16) 'test'
该数据还与 gzip 模块兼容:
>>> import gzip >>> import StringIO >>> fio = StringIO.StringIO(gzip_data) >>> f = gzip.GzipFile(fileobj=fio) >>> f.read() 'test' >>> f.close()
将 32 添加到 windowBits 将触发标头检测
32
>>> zlib.decompress(gzip_data, zlib.MAX_WBITS|32) 'test' >>> zlib.decompress(zlib_data, zlib.MAX_WBITS|32) 'test'
对于带有gzip标头的 gzip 数据,您可以直接使用 gzip 模块;但please remember that under the hood, gzip 使用 zlib .
fh = gzip.open('abc.gz', 'rb') cdata = fh.read() fh.close()
zlib和gzip的结构不同 . zlib使用RFC 1950,gzip使用RFC 1952,因此具有不同的 Headers ,但其余的具有相同的结构并遵循RFC 1951 .
Node.js
const { gunzip } = require('zlib'); const decompressGzip = compressedData => new Promise((resolve, reject) => { gunzip(compressedData, (error, decompressedData) => { if (error) return reject(error); return resolve(decompressedData); }); }); module.exports = { decompressGzip };
您使用纱线安装 zlib
yarn add zlib
4 回答
要使用zlib解压缩gzip格式文件,请使用
windowBits
参数调用inflateInit2
作为16+MAX_WBITS
,如下所示:如果你不这样做,zlib会抱怨一个糟糕的流格式 . 默认情况下,zlib使用zlib标头创建流,并且在inflate中无法识别不同的gzip标头,除非您这样说 . 虽然从
zlib.h
头文件的1.2.1版开始记录了这一点,但它不在zlib manual中 . 从头文件:python
zlib library supports:
RFC 1950(
zlib
压缩格式)RFC 1951(
deflate
压缩格式)RFC 1952(
gzip
压缩格式)python
zlib
模块也将支持这些 .选择windowBits
但
zlib
可以解压缩所有这些格式:到(de-)压缩
deflate
格式,使用wbits = -zlib.MAX_WBITS
到(de-)压缩
zlib
格式,使用wbits = zlib.MAX_WBITS
到(de-)压缩
gzip
格式,使用wbits = zlib.MAX_WBITS | 16
请参阅http://www.zlib.net/manual.html#Advanced中的文档(第
inflateInit2
节)例子
测试数据:
zlib
的明显测试:测试
deflate
:测试
gzip
:该数据还与
gzip
模块兼容:自动标头检测(zlib或gzip)
将
32
添加到windowBits
将触发标头检测使用gzip代替
对于带有gzip标头的
gzip
数据,您可以直接使用gzip
模块;但please remember that under the hood,gzip
使用zlib
.zlib和gzip的结构不同 . zlib使用RFC 1950,gzip使用RFC 1952,因此具有不同的 Headers ,但其余的具有相同的结构并遵循RFC 1951 .
Node.js
您使用纱线安装
zlib