Python:使用 tarfile 从 TAR 存档中删除文件



是否可以使用tarfile从 TAR 存档中删除某些文件?

例如:

如果x.tar文件包含文件a.txtb.txtc.txt,是否可以删除a.txt

换句话说:是否存在任何 python 解决方案来实现这样的事情:

tar -vf x.tar --delete a.txt

不直接使用tarfile,尽管可能还有其他一些库。您可以做的一个快速技巧是提取文件,然后重新创建tar减去要删除的文件。

我遇到了类似的问题,最终使用了 7z 命令行 (7za.exe),因为它支持比 Python 的tarfile更多的功能,包括从存档中删除文件。

此解决方案的缺点是您需要随程序携带 7za.exe 文件。

在您的情况下,您可以使用类似的东西

os.system("7za d x.tar a.txt")

但请记住,os.system已被弃用,您应该使用subprocess.从来没有用过它,所以我真的帮不上更多忙。

事实上,有可能...但有巨大的限制。您只能删除存档的末尾/尾部,而不能删除存档开头或中间的文件.
我只是有类似的需求,即从巨大的 tar (450G) 中提取文件,没有足够的空间容纳 tar 和提取的文件。我必须一次提取一个文件,并在解压缩后立即将它们从.tar中删除.
命令tar -vf x.tar --delete a.txt不能解决这个问题,因为它不会从x.tar中删除a.txt(x.tar保持相同的大小),它只是将其从包含的文件列表中删除(稍后解压缩x.tar时不会提取a.txt)。
.tar文件,您唯一能做的就是截断它们,因为它们是连续的。所以唯一的解决方案是从 end.
首先获取 tar 文件所有成员的列表:

with tarfile.open(name=tar_file_path, mode="r") as tar_file:
tar_members = tar_file.getmembers()

然后,您可以从末尾提取所需的文件:

with tarfile.open(name=tar_file_path, mode="r") as tar_file:
tar_file.extractall(path = extracting_dir, members = tar_members[first_of_files_to_extract:])

您可以计算截断文件的位置(以字节为单位):

truncate_size = tar_members[first_of_files_to_extract].offset

然后添加"文件结束"标记,即两个连续的 Null 块。每个块的长度为 512 字节.tar,因此您需要在末尾有 1024 个空字节。在这里,仅作为记录,您可以添加 512 字节(一个块),因为前一个tar_member已经以 512 字节 Null 块(tar_member结尾的标记)完成。

new_file_size = truncate_size + 1024 # 2 blocs of 512 Null bytes 

最后你做了截断,首先用于删除最后一个成员,其次用于添加空字节(这里我们不再打开带有tarfile.open().tar,截断只是常规的文件操作):

with open(tar_file_path) as tar_file:
tar_file.truncate(truncate_size)
tar_file.truncate(new_file_size)

在这里,您已经从.tar末尾提取了文件,并且您有一个新的有效.tar文件,通过提取文件的大小加上一些块字节,比前一个文件小,并且您已将额外的内存使用限制为提取文件的大小: 我个人逐个文件做了那个文件(提取最后一个文件, 截断,提取最后一个文件截断等)。

最新更新