Python 3.6使用zipfile模块生成不含绝对路径的压缩包
如何用Python的zipfile模块保留指定起始目录结构生成压缩包
我完全懂你要实现的需求——就是把指定的目标文件夹(比如你的Documents)连同它下面的所有子目录、文件一起打包,而且压缩包里只保留从这个目标文件夹开始的目录结构,不会把它的上级目录(比如OneDrive、User1这些)也带进去对吧?我帮你完善了代码,还把关键细节拆解清楚,你直接用就行:
import zipfile import os import datetime def backup(src, dest): """Backup files from src to dest, preserving directory structure starting at src.""" # 提取我们要作为压缩包根目录的文件夹名称(比如传入Documents路径,这里拿到"Documents") root_folder = os.path.basename(src) # 生成带时间戳的压缩包文件名,避免每次备份覆盖旧文件 timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") zip_filename = f"{root_folder}_backup_{timestamp}.zip" zip_path = os.path.join(dest, zip_filename) # 创建压缩包,用ZIP_DEFLATED模式开启压缩(比默认的仅存储模式更省空间) with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf: # 遍历源目录下的所有文件和文件夹 for dirpath, dirnames, filenames in os.walk(src): # 计算当前目录在压缩包内的相对路径:把src的上级路径去掉,换成root_folder开头的路径 relative_dir = os.path.relpath(dirpath, os.path.dirname(src)) # 把空文件夹也添加到压缩包里(默认zipfile不会自动加空文件夹) if relative_dir != ".": zipf.write(dirpath, relative_dir) # 遍历当前目录下的所有文件,逐个添加到压缩包 for filename in filenames: file_path = os.path.join(dirpath, filename) # 计算文件在压缩包内的相对路径 relative_file_path = os.path.join(relative_dir, filename) zipf.write(file_path, relative_file_path) print(f"备份搞定!压缩包已经存到:{zip_path}") # 示例用法,直接改这里的路径就行 if __name__ == "__main__": # 要备份的源目录(换成你自己的Documents路径) source_dir = r"C:\Users\User1\OneDrive\Documents" # 压缩包要保存的目标目录(自己选个地方) destination_dir = r"C:\Users\User1\Backups" # 确保目标目录存在,不存在就自动创建 os.makedirs(destination_dir, exist_ok=True) backup(source_dir, destination_dir)
关键细节说明
- 核心:相对路径计算:
os.path.relpath(dirpath, os.path.dirname(src))是实现目录结构保留的关键。比如当遍历到C:\Users\User1\OneDrive\Documents\Photos时,这个方法会返回Documents\Photos,刚好就是我们要在压缩包里保留的路径。 - 空文件夹处理:默认情况下zipfile不会主动添加空文件夹,所以我们手动遍历目录时把它们加进去,确保整个目录结构完整。
- 时间戳文件名:给压缩包加上当前时间戳,避免每次备份覆盖之前的文件,方便回溯版本。
- 压缩模式:用
zipfile.ZIP_DEFLATED开启压缩,比默认的ZIP_STORED(只存储不压缩)能节省不少磁盘空间。
额外小提示
- 如果需要排除某些文件或文件夹(比如临时文件、
.git目录),可以在遍历的时候加判断,比如:if ".git" in dirpath: continue - 大文件备份也不用担心内存问题,zipfile的
write方法是逐块处理文件的,不会一次性把整个文件读进内存。 - 路径里有中文或特殊字符也没问题,Python 3.6+对路径的编码支持已经很完善了。
内容的提问来源于stack exchange,提问作者Jeff Moorhead
相关产品推荐
相关产品推荐

