Python解压缩gzip chunk-by-chunk

时间:2010-03-11 09:35:35

标签: python gzip zlib

我有一个内存和磁盘限制的环境,我需要解压缩基于字符串的块(通过xmlrpc二进制传输)发送给我的gzip文件的内容。但是,在gzip头上使用zlib.decompress()或zlib.decompressobj()/ decompress()两个barf。我试过偏移gzip标题(记录here),但仍未设法避开barf。 gzip库本身似乎只支持从文件解压缩。

下面的代码片段简要说明了我想要做的事情(现实生活中除了从xmlrpc填充缓冲区,而不是从本地文件中读取):

#! /usr/bin/env python

import zlib

CHUNKSIZE=1000

d = zlib.decompressobj()

f=open('23046-8.txt.gz','rb')
buffer=f.read(CHUNKSIZE)

while buffer:
  outstr = d.decompress(buffer)
  print(outstr)
  buffer=f.read(CHUNKSIZE)

outstr = d.flush()
print(outstr)

f.close()

不幸的是,正如我所说,这个barfs:

Traceback (most recent call last):
  File "./test.py", line 13, in <module>
    outstr = d.decompress(buffer)
zlib.error: Error -3 while decompressing: incorrect header check 

理论上,我可以将我的xmlrpc源数据提供给StringIO,然后将其用作gzip.GzipFile()的fileobj,但是,在现实生活中,我没有可用于保存整个文件内容的内存内存以及解压缩的数据。我确实需要逐块处理它。

后退将是将我的xmlrpc源数据的压缩从gzip更改为普通zlib,但由于这会影响其他子系统,我希望尽可能避免使用它。

有什么想法吗?

2 个答案:

答案 0 :(得分:41)

gzip和zlib使用略有不同的标题。

请参阅How can I decompress a gzip stream with zlib?

尝试d = zlib.decompressobj(16+zlib.MAX_WBITS)

出于可能的性能原因,您可能会尝试将块大小更改为2的幂(比如CHUNKSIZE=1024)。

答案 1 :(得分:3)

我在这里得到了更详细的答案:https://stackoverflow.com/a/22310760/1733117

d = zlib.decompressobj(zlib.MAX_WBITS|32)

per documentation this automatically detects the header (zlib or gzip)