1

当我尝试使用 gzip 库使用 python 读取 gz 文件时,它会产生一个错误,就像您尝试在其上运行 gunzip 一样。但是,可以使用 perl 来执行此操作,因为我不相信它使用的库会额外检查正在读取的文件上是否有干净的 EOF。

我的问题是是否有任何选项或替代库可以在 python 中读取这样的文件,或者我只需要在 perl 中执行此操作?

4

2 回答 2

3

标准 Python 库可以用于此,尽管比完整文件更笨拙。

>>> import zlib
>>> compressed=zlib.compress(str(range(200)))
>>> len(compressed)
375
>>> trunc=compressed[:50]
>>> zlib.decompress(trunc)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
zlib.error: Error -5 while decompressing data: incomplete or truncated stream
>>> d=zlib.decompressobj()
>>> d.decompress(trunc)
'[0, 1, 2, 3, 4, 5, 6, 7, 8, 9'
>>> d.flush()
''

请注意, decompressobj.flush() 请求最后一个数据,因此仅在输入流结束后调用它(或在副本上 - 有一个 decompressobj.copy() 方法)。您可以根据需要使用尽可能多的 decompressobj.decompress() 调用来输入压缩数据。

>>> d=zlib.decompressobj()
>>> for i in range(0,140,10):
...   print repr(d.decompress(compressed[i:i+10]))
...
''
''
''
'[0, 1, 2, 3, 4'
', 5, 6, 7, 8, 9'
', 10, 11, 12, 13, 14, 15, 16, '
'17, 18, 19, 20, 21, 22, 23, '
'24, 25, 26, 27, 28, 29, 3'
'0, 31, 32, 33, 34, 35, 36, '
'37, 38, 39, 40, 41, 42, 4'
'3, 44, 45, 46, 47, 48, 49, '
'50, 51, 52, 53, 54, 55, 5'
'6, 57, 58, 59, 60, 61, 62, 6'
'3, 64, 65, 66, 67, 68, 6'
>>> d.flush()
''

(我没有看到 flush() 实际上返回任何东西,但这可能是因为这是一个如此简单的数据样本。)

编辑:我错过了一分。Gzip 文件具有 gzip 模块通常处理的标头,因此对 zlib 的原始访问不会直接读取 gzip 文件。使用 GzipFile 并以较小的块读取可能会更容易。

于 2013-10-01T13:31:55.467 回答
1

要解压缩内存中不完整的压缩字节,Yann Vernier 的答案很有用,但它错过了wbits我认为必要的 arg:

incomplete_decompressed_content = zlib.decompressobj(wbits=zlib.MAX_WBITS | 16).decompress(incomplete_gzipped_content)

请注意,这zlib.MAX_WBITS | 1615 | 1631。有关 的一些背景信息wbits,请参阅zlib.decompress


学分:dnozay 的回答,wbits它指出了不同编码所需的不同值的下限。

于 2019-06-22T21:23:48.463 回答