【发布时间】:2022-01-14 19:26:15
【问题描述】:
我有一个 .tar 文件,其中包含一个文件夹内的许多 .gz 文件。这些 gz 文件中的每一个都包含一个 .txt 文件。与此问题相关的其他 stackoverflow 问题旨在提取文件。
我正在尝试迭代读取每个 .txt 文件的内容而不提取它们,因为 .tar 很大。
首先我阅读了 .tar 文件的内容:
import tarfile
tar = tarfile.open("FILE.tar")
tar.getmembers()
或者在 Unix 中:
tar xvf file.tar -O
然后我尝试使用 tarfile extractfile 方法,但出现错误:“模块 'tarfile' 没有属性 'extractfile'”。此外,我什至不确定这是正确的方法。
import gzip
for member in tar.getmembers():
m = tarfile.extractfile(member)
file_contents = gzip.GzipFile(fileobj=m).read()
如果你想创建一个示例文件来模拟原始文件:
$ mkdir directory
$ touch directory/file1.txt.gz directory/file2.txt.gz directory/file3.txt.gz
$ tar -c -f file.tar directory
这是在使用 Mark Adler 的建议后对我有用的最终版本:
import tarfile
tar = tarfile.open("file.tar")
members = tar.getmembers()
# Here I append the results in a list, because I wasn't able to
# parse the tarfile type returned by .getmembers():
tar_name = []
for elem in members:
tar_name.append(elem.name)
# Then I changed tarfile.extractfile to tar.extractfile as suggested:
for member in tar_name:
# I'm using this because I have other non-gzs in the directory
if member.endswith(".gz"):
m=tar.extractfile(member)
file_contents = gzip.GzipFile(fileobj=m).read()
【问题讨论】:
-
你还没有,或者至少没有表现出来,很多尝试在这里。展示你尝试了什么、发生了什么以及你期望什么。不要遗漏代码。例如。您将
tar.getmembers()显示为已阅读内容,但除非您阅读了tar = tarfile.open("FILE.tar"),否则这是行不通的。你漏掉了tar =。如果您要在问题中添加代码,请准确地输入您所做的,而不是与您所做的模糊相似的内容。 -
感谢您的意见。有时在粘贴和重新格式化时,我删除了 tar 变量。
-
您可以使用
tar.getnames()直接获取姓名列表。我敢打赌,你工作程序中的实际内容是if member.endswith(".gz"):。复制和粘贴是您的朋友。 -
.tar 文件不包含所有成员的目录(如 .zip 文件中),而仅包含文件头和文件数据块的序列。如果要检索成员列表,则必须读取完整文件中的所有标题。这可以通过查找文件中的特定位置来实现,但它会从文件中从头到尾的各个位置读取数据。如果您按照存档中出现的顺序读取一个文件头、检查文件名、提取数据、转到下一个文件头等,整体性能可能会更好。