Python tar文件如何将文件提取到流中

13

我想要解压缩一个文件夹,但是不想直接使用 .extractall(),而是想要将文件解压到流中,以便我自己处理这个流。是否可以使用 tarfile 实现?或者有其他的建议吗?


你是指 tarfile 库吗? - Chris Medrela
是的,抱歉打错字了。 - Robin W.
2个回答

23

你可以使用.extractfile()方法将tar文件中的每个文件作为python file对象获取。循环遍历tarfile.TarFile()实例,以列出所有条目:

import tarfile

with tarfile.open(path) as tf:
    for entry in tf:  # list each entry one by one
        fileobj = tf.extractfile(entry)
        # fileobj is now an open file object. Use `.read()` to get the data.
        # alternatively, loop over `fileobj` to read it line by line.

2
如果fileobj是一个gzip文件,是否可以对其进行解压缩? - Werner
1
@Werner:tarfile模块会自动处理压缩。请参阅tarfile.open()文档,默认模式为r,可以透明地检测压缩并在需要时进行解压缩。 - Martijn Pieters
2
是的,但在tar文件中我有一个gzip文件(不幸的是,有人用我的gzip文件创建了一个压缩的tar文件...)。extractfile返回一个tarfile.ExFileObject,不能用于打开gzip.GzipFile。是否有一种方法可以在不解压缩tar文件并打开新系统文件的情况下打开此gzip文件? - Werner
1
@Werner:我猜你在使用Python 2,是吗?Python 3的gzip模块应该可以无问题地接受该对象,但Python 2版本仍然尝试在文件对象上寻找。要么升级到Python 3,要么先将文件复制到磁盘上,或者在读取时解码流,参见Python逐块解压缩gzip - Martijn Pieters
是的,仍然在使用 Python 2,不幸的是,由于它是环境的一部分,无法升级。好的,非常感谢!我找不到任何关于这个的信息... - Werner
显示剩余3条评论

1

在使用网络流传输tar文件时,我无法执行extractfile操作,所以我尝试了以下方法:

from backports.lzma import LZMAFile
import tarfile
some_streamed_tar = LZMAFile(requests.get('http://some.com/some.tar.xz').content)
with tarfile.open(fileobj=some_streamed_tar) as tf:
    tarfileobj.extractall(path="/tmp", members=None)

然后阅读它们:

for fn in os.listdir("/tmp"):
    with open(os.path.join(t, fn)) as f:
        print(f.read())

python 2.7.13


您也可以直接使用流式传输来实现此目的,即无需任何临时文件:https://dev59.com/JZHea4cB1Zd3GeqPtLoN#34131505 - vog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接