39

我有一个内存和磁盘受限的环境,我需要解压缩以基于字符串的块(通过 xmlrpc 二进制传输)发送给我的 gzip 文件的内容。但是,使用 zlib.decompress() 或 zlib.decompressobj()/decompress() 两者都会对 gzip 标头产生影响。我尝试过抵消 gzip 标头(在此处记录),但仍然无法避免出现问题。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()

不幸的是,正如我所说,这令人讨厌:

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,但由于这会影响其他子系统,我希望尽可能避免它。

有任何想法吗?

4

2 回答 2

52

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

请参阅如何使用 zlib 解压缩 gzip 流?

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

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

于 2010-03-11T11:40:57.387 回答
4

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

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

根据文档,这会自动检测标头(zlib 或 gzip)

于 2014-03-10T22:25:04.927 回答