你能用python读取一个不正确关闭的gz文件吗?

时间:2013-10-01 13:13:05

标签: python gzip

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

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

-mark

2 个答案:

答案 0 :(得分:2)

标准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并以较小的块读取可能更容易。

答案 1 :(得分:1)

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

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

请注意,zlib.MAX_WBITS | 1615 | 16,即31。有关wbits的背景知识,请参见zlib.decompress


信用:answer by dnozay指出了不同编码所需的wbits不同值的下限。