Python解压缩gzip chunk-by-chunk

Python decompressing gzip chunk-by-chunk

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#! /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:

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

有任何想法吗?


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

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

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

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


我在这里有一个更详细的答案:https://stackoverflow.com/a/22310760/1733117

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

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