Python 按块解压 gzip
我有一个内存和磁盘都有限的环境,需要解压缩通过字符串块发送给我的gzip文件内容(是通过xmlrpc二进制传输的)。但是,使用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()的文件对象,但实际上,我没有足够的内存来同时存放整个文件内容和解压后的数据。我确实需要逐块处理。
一个备选方案是把xmlrpc传来的数据的压缩格式从gzip改成普通的zlib,但这会影响其他子系统,所以如果可以的话,我希望避免这样做。
有没有什么好的建议?
2 个回答
4
我这里有一个更详细的回答:https://stackoverflow.com/a/22310760/1733117
d = zlib.decompressobj(zlib.MAX_WBITS|32)
57
gzip和zlib使用的头部信息稍微有点不同。
可以参考这个链接:如何用zlib解压gzip流?
你可以试试这个代码:d = zlib.decompressobj(16+zlib.MAX_WBITS)
。
另外,你也可以尝试把你的数据块大小改成2的幂次方,比如说CHUNKSIZE=1024
,这样可能会提高性能。