【问题标题】:Python decompressing gzip chunk-by-chunkPython逐块解压缩gzip
【发布时间】:2011-01-26 07:15:24
【问题描述】:

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

下面的 sn-p 给出了我想做的简化说明(除了在现实生活中缓冲区将由 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,但由于这会影响其他子系统,我希望尽可能避免它。

有什么想法吗?

【问题讨论】:

    标签: python gzip zlib


    【解决方案1】:

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

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

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

    【讨论】:

    • 我不想对你投反对票,但这对我来说根本行不通。
    • @gwg 尝试更精确,例如,什么特别不适合您。否则,人们将无法帮助您。感谢您的理解。
    • 我不是在寻求帮助,因为接受的答案对我有用。我正在注册此意见以节省其他人的时间。
    【解决方案2】:

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

    How can I decompress a gzip stream with zlib?

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

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

    【讨论】:

    • 做得很完美。谢谢。 (现在,为什么 python 文档中没有这个提示?)
    • zlib 只是 zlib 的 c 版本的包装器。它根本没有很好的记录。请注意,16+zlib.MAX_WBITS 也没有记录 c 版本,这不是我第一次看到未记录的 zlib 功能。
    • 肯定需要记录在案!
    • 直到昨天这对我来说都很好。我在这里有一个 gziped 文件,可以使用命令行 gzip 很好地解压缩,使用 python 中的 gzip 模块可以很好地解压缩,但使用 zlib 会过早停止。如其他地方所述,gzip 需要一个真实文件(它可以在其上 seek()),所以我现在在市场上寻找替代 gzip 和/或 zlib 实现。
    • 谢谢!这应该在一些官方文档中注明。我为此奋斗了好几个小时……
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-02
    • 2021-11-15
    • 2023-03-18
    • 1970-01-01
    • 2012-02-12
    • 2012-09-25
    • 2011-12-06
    相关资源
    最近更新 更多