如何将嵌套子文件夹同步复制到备份目录?
解决方案
完全不用删除整个备份目录,我们可以通过映射源路径到备份路径的方式,逐层同步嵌套文件夹和文件,以下是具体实现思路和代码:
核心思路
遍历源目录的每个文件/文件夹时,将源路径中的「源根目录」替换为「备份根目录」,得到对应的备份路径,然后:
- 若是文件:先确保备份路径的父目录存在,再复制文件(保留元数据)
- 若是文件夹:创建对应的备份文件夹(已存在则跳过),再递归处理子目录
修复后的代码实现
方法1:使用os.walk(更简洁)
import os import shutil def sync_backup(source_root, backup_root): # 遍历源目录的所有层级 for source_path, dirs, files in os.walk(source_root): # 计算当前源路径对应的备份路径 relative_path = os.path.relpath(source_path, source_root) backup_path = os.path.join(backup_root, relative_path) # 创建备份目录(已存在则忽略) os.makedirs(backup_path, exist_ok=True) # 同步当前目录下的所有文件 for file_name in files: source_file = os.path.join(source_path, file_name) backup_file = os.path.join(backup_path, file_name) # 可选:只复制比备份文件新的文件(增量同步) if not os.path.exists(backup_file) or os.path.getmtime(source_file) > os.path.getmtime(backup_file): shutil.copy2(source_file, backup_file)
方法2:使用os.scandir(性能更优)
import os import shutil def sync_folder(source_path, backup_root, source_root): for entry in os.scandir(source_path): # 计算当前条目对应的备份路径 relative_path = os.path.relpath(entry.path, source_root) backup_entry_path = os.path.join(backup_root, relative_path) if entry.is_file(): # 确保父目录存在 os.makedirs(os.path.dirname(backup_entry_path), exist_ok=True) # 复制文件(可选增量判断) if not os.path.exists(backup_entry_path) or os.path.getmtime(entry.path) > os.path.getmtime(backup_entry_path): shutil.copy2(entry.path, backup_entry_path) elif entry.is_dir(): # 创建备份目录 os.makedirs(backup_entry_path, exist_ok=True) # 递归处理子目录 sync_folder(entry.path, backup_root, source_root) # 调用示例 sync_folder(source_root, backup_root, source_root)
解决你遇到的具体问题
os.makedirs报错:添加exist_ok=True参数,即可忽略已存在的目录,避免报错。- 路径替换:通过
os.path.relpath获取当前路径相对于源根目录的相对路径,再拼接备份根目录,就能得到对应的备份路径,不用手动字符串替换(更鲁棒)。 - 嵌套目录同步:递归处理每个子目录时,传递正确的备份路径,确保每个层级的目录都对应创建到备份目录中。
额外优化
- 增量同步:通过对比文件修改时间(
os.path.getmtime)或者哈希值,只复制更新过的文件,提升同步效率。 - 处理删除:如果需要同步源目录中删除的文件/文件夹,可以记录上次同步的文件列表,对比后删除备份目录中多余的条目(可选需求)。
内容的提问来源于stack exchange,提问作者Coder101
相关产品推荐
相关产品推荐

