Python遍历大型嵌套目录时,如何从上次失败的迭代处恢复?
断点续传修改方案
要解决VPN断开后重新运行代码能从最后处理的文件继续的问题,核心是持久化记录已成功上传的文件路径,下次启动时直接跳过这些文件。以下是具体修改步骤和代码:
关键思路
- 用本地文件存储已处理的文件路径(避免放在网络驱动器,防止VPN断开时无法写入)
- 启动时加载已处理记录,存入集合以实现O(1)效率的查找
- 处理每个文件前先检查是否已处理,未处理则执行上传,成功后追加记录
- 捕获上传异常,确保未成功上传的文件不会被标记为已处理
修改后的完整代码
import os import boto3 # 需确保已安装boto3库 # 初始化S3客户端(根据你的AWS配置调整) s3_client = boto3.client('s3') bucket = 'your-bucket-name' # 替换为你的S3桶名 processed_log = 'processed_files.txt' # 本地记录文件,务必放在本地磁盘 def load_processed_files(log_path): """加载已处理的文件路径集合""" processed = set() if os.path.exists(log_path): with open(log_path, 'r', encoding='utf-8') as f: for line in f: path = line.strip() if path: processed.add(path) return processed def mark_processed(log_path, file_path): """标记文件为已处理,追加写入记录文件""" with open(log_path, 'a', encoding='utf-8') as f: f.write(f"{file_path}\n") def get_target_file(source_file, root_dir, s3_prefix=''): """将网络文件路径转换为S3存储的目标键(按需调整)""" relative_path = os.path.relpath(source_file, root_dir) return os.path.join(s3_prefix, relative_path).replace('\\', '/') # S3路径用正斜杠 if __name__ == "__main__": directory = '//DirectoryName/FolderName' normalized_dir = os.path.normpath(directory) processed_files = load_processed_files(processed_log) for root, dirs, files in os.walk(normalized_dir, topdown=False): for name in files: source_file = os.path.join(root, name) # 跳过已处理的文件 if source_file in processed_files: print(f"跳过已处理文件: {source_file}") continue try: # 生成S3目标文件路径 target_file = get_target_file(source_file, normalized_dir) # 执行上传 s3_client.upload_file(source_file, bucket, target_file) # 上传成功后标记为已处理 mark_processed(processed_log, source_file) print(f"成功上传: {source_file}") except Exception as e: print(f"处理文件 {source_file} 失败: {str(e)}") # 遇到VPN断开这类致命异常时退出,避免批量错误 # 若需尝试处理其他可访问文件,可注释掉下面的raise raise
注意事项
- 记录文件位置:
processed_files.txt必须放在本地磁盘,不能放在网络驱动器,否则VPN断开时无法写入记录。 - S3目标路径:
get_target_file函数需根据你的存储需求调整,确保网络文件路径能正确映射到S3的存储键。 - 异常处理:保留
raise会在遇到错误时直接退出程序,适合VPN断开的场景;若需继续处理其他可访问文件,可移除raise改为继续循环。 - 性能适配:用集合存储已处理路径,查找效率极高,能轻松应对数千文件的规模。
- 重复运行安全:即使重复运行已处理完的文件,程序会自动跳过,不会重复上传。
内容的提问来源于stack exchange,提问作者Devansh Popat
相关产品推荐
相关产品推荐

