从 Python 中的串联 gzip 中读取多个文件

Read multiple files from concatenated gzip in Python

如果我有一个 gzip 文件并将其与另一个 gzip 文件连接在一起,是否可以在 python 中单独读取这些文件?

例如:

cat f1.csv.gz f2.csv.gz > f3.csv.gzip

我知道这在 Go 中是可能的,但是在 Python 中有没有办法做到这一点?

是的。使用z = zlib.decompressobj(31),然后使用z解压,直到z.unused_data不为空,或者你已经处理完所有的输入。如果 z.unused_data 不是空的,那么它包含下一个 gzip 流的开始。创建一个新的 y = zlib.decompressobj 对象,并使用 z.unused_data 的内容开始解压缩,继续从文件中获取更多数据。

这将打印每个串联的 gzip 组件的未压缩大小:

#!/usr/bin/python
import sys
import zlib
z = zlib.decompressobj(31)
count = 0
while True:
    if z.unused_data == "":
        buf = sys.stdin.read(8192)
        if buf == "":
            break
    else:
        print count
        count = 0
        buf = z.unused_data
        z = zlib.decompressobj(31)
    got = z.decompress(buf)
    count += len(got)
print count

@MarkAdler 非常感谢您的回答。它实际上对我帮助很大!

现在我只想添加一个可以节省您大量时间的小细节。当前的答案不会检测截断的文件,例如 gzip/zcat。

zcat file.gz 
gzip: file.gz: unexpected end of file

要更正此问题,请检查 decompress.oef。如果为 False,这意味着 gzip 文件被截断。如果不这样做,您将永远不会看到错误。

修改后的代码如下:

#!/usr/bin/python
import sys
import zlib
z = zlib.decompressobj(31)
count = 0
while True:
    if z.unused_data == "":
        buf = sys.stdin.read(8192)
        if buf == "":
            # check truncated file
            if not z.eof:
                raise RuntimeError("unexpected end of file")
            break
    else:
        print count
        count = 0
        buf = z.unused_data
        z = zlib.decompressobj(31)
    got = z.decompress(buf)
    count += len(got)
print count