如何在Python中无需重写即可删除压缩tar文件中的文件
解决方案
一、Python 3 删除 tar 文件中的指定文件
tar 格式本身不支持直接删除内部文件,只能通过重新构建归档的方式实现,针对大文件可以用流式处理避免内存溢出:
import tarfile def remove_file_from_tar(source_tar_path, dest_tar_path, file_to_remove): with tarfile.open(source_tar_path, 'r') as src_tar, tarfile.open(dest_tar_path, 'w') as dest_tar: for member in src_tar.getmembers(): # 跳过要删除的文件 if member.name != file_to_remove: # 流式复制文件内容,避免加载整个文件到内存 file_obj = src_tar.extractfile(member) dest_tar.addfile(member, file_obj)
注意:如果是压缩格式的 tar(如 .tar.gz/.tar.bz2),'r' 会自动识别压缩格式,写入新 tar 时需要指定对应压缩模式(比如 'w:gz')。
二、向大体积 tar 文件追加可修改的额外信息(兼容加密场景)
由于后续要对 tar 文件设置密码保护,直接追加内容后无法通过 .split() 拆分修改,推荐两种可行方案:
方案1:在 tar 内部预留可修改的元数据文件
生成 tar 时,添加一个固定占位的元数据文件(比如 metadata.json),后续需要修改时,通过流式处理只替换该文件,无需重写整个归档的其他内容:
import tarfile import io def update_tar_metadata(source_tar_path, dest_tar_path, new_metadata): # 将新元数据转为字节流 metadata_bytes = new_metadata.encode('utf-8') with tarfile.open(source_tar_path, 'r') as src_tar, tarfile.open(dest_tar_path, 'w') as dest_tar: for member in src_tar.getmembers(): if member.name == 'metadata.json': # 创建新的元数据文件成员 new_member = tarfile.TarInfo('metadata.json') new_member.size = len(metadata_bytes) new_member.mtime = member.mtime # 保留原时间或设置新时间 dest_tar.addfile(new_member, io.BytesIO(metadata_bytes)) else: file_obj = src_tar.extractfile(member) dest_tar.addfile(member, file_obj)
方案2:使用独立的加密元数据文件
如果不想重新生成大体积 tar 文件,可将元数据存储在与 tar 文件同名的独立加密文件中(比如 archive.tar.meta.gpg)。修改时只需解密这个小文件、更新内容后重新加密,完全不影响主 tar 文件,这种方式效率最高,也避免了修改大文件的开销。
内容的提问来源于stack exchange,提问作者Konstantin
相关产品推荐
相关产品推荐

