Python tarfile打包时tar包内生成多余嵌套子目录问题
问题原因
- 归档出现多层嵌套目录:
tarfile.add()方法默认会保留传入文件路径的完整目录结构,传入文件绝对路径时,打包时就会从根目录开始逐层创建对应文件夹,最终文件被存到最深层目录。 - 直接传文件名报
FileNotFoundError:Python运行时的当前工作目录不是你指定的source目录,程序在当前工作路径下找不到对应文件名的文件,就会抛出找不到文件的错误。
解决方法
最简便的方案是利用tar.add()的arcname参数,手动指定文件在tar归档内的存储路径,不需要切换工作目录,也不会影响其他代码逻辑:
import tarfile import os archive_path = '/home/atom/Desktop/test_arch/sample.tar' source_dir = '/home/atom/Desktop/test_arch' file_list = os.listdir(source_dir) file_list.sort() with tarfile.open(archive_path, "w") as tar: for file_name in file_list: full_path = os.path.join(source_dir, file_name) # 跳过正在生成的tar包本身,避免把归档文件自己打包进去 if os.path.abspath(full_path) == os.path.abspath(archive_path): continue print(file_name) # arcname指定归档内的存储名称,直接传文件名就不会生成多余嵌套目录 tar.add(full_path, arcname=file_name)
这里用with上下文管理器会自动处理tar文件的关闭,比手动写close()更稳妥;用os.path.join()拼接路径比手动加/兼容性更好,在Windows系统下也能正常运行。
如果需要递归打包源目录下所有子目录内的文件,同时保留源目录内部的相对结构、不带上外层的绝对路径,可以搭配os.walk实现:
import tarfile import os archive_path = '/home/atom/Desktop/test_arch/sample.tar' source_dir = '/home/atom/Desktop/test_arch' with tarfile.open(archive_path, "w") as tar: for root, dirs, files in os.walk(source_dir): for file_name in files: full_path = os.path.join(root, file_name) if os.path.abspath(full_path) == os.path.abspath(archive_path): continue # 计算文件相对于源目录的相对路径,作为归档内的存储路径 rel_path = os.path.relpath(full_path, source_dir) tar.add(full_path, arcname=rel_path)
内容的提问来源于stack exchange,提问作者djangodjames
相关产品推荐
相关产品推荐

