如何使用zlib解压缩gzipstream?

Gzip格式文件(例如使用gzip程序创build)使用“deflate”压缩algorithm,这与zlib使用的压缩algorithm相同。 但是,使用zlib来Z_DATA_ERROR gzip压缩文件时,库会返回一个Z_DATA_ERROR

我如何使用zlib解压缩gzip文件?

要使用zlib解压缩gzip格式的文件,请使用windowBits参数(如16+MAX_WBITS ,如下所示:

 inflateInit2(&stream, 16+MAX_WBITS); 

如果你不这样做,zlib会抱怨stream格式不正确。 默认情况下,zlib使用zlib标题创buildstream,在inflate上不能识别不同的gzip标题,除非你这么说。 尽pipe从zlib.h头文件的1.2.1版开始logging,但它不在zlib手册中 。 从头文件:

对于可选的gzip解码, windowBits也可以大于15。 将32添加到windowBits以启用自动头检测的zlib和gzip解码,或者添加16来仅解码gzip格式(zlib格式将返回Z_DATA_ERROR )。 如果正在解码gzipstream,则strm->adler是crc32而不是adler32。

python

zlib库支持 :

  • RFC 1950 ( zlib压缩格式)
  • RFC 1951 ( deflate压缩格式)
  • RFC 1952 ( gzip压缩格式)

python zlib模块也将支持这些。

selectwindowBits

但是zlib可以解压缩所有这些格式:

  • (去)压缩deflate格式,使用wbits = -zlib.MAX_WBITS
  • 以(去)压缩zlib格式,使用wbits = zlib.MAX_WBITS
  • 以(去)压缩gzip格式,使用wbits = zlib.MAX_WBITS | 16 wbits = zlib.MAX_WBITS | 16

请参阅http://www.zlib.net/manual.html#Advanced(section inflateInit2 )中的文档

例子

testing数据:

 >>> 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() >>> 

明显的zlibtesting:

 >>> zlib.decompress(zlib_data) 'test' 

testingdeflate

 >>> 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' 

testinggzip

 >>> 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() 

自动标题检测(zlib或gzip)

windowBits添加32会触发标题检测

 >>> zlib.decompress(gzip_data, zlib.MAX_WBITS|32) 'test' >>> zlib.decompress(zlib_data, zlib.MAX_WBITS|32) 'test' 

使用gzip来代替

对于使用gzip头的gzip数据,您可以直接使用gzip模块; 但请记住引擎盖下 , gzip使用zlib

 fh = gzip.open('abc.gz', 'rb') cdata = fh.read() fh.close() 

zlib和gzip的结构是不同的。 zlib使用RFC 1950,而gzip使用RFC 1952 ,所以有不同的头文件,但其余的具有相同的结构并遵循RFC 1951 。

Interesting Posts