如何优化移除文件夹特定旧文件仅保留最新版的Python代码?
优化文件夹旧文件清理逻辑,保留最新带时间戳的EMSRP文件
你的需求是清理文件夹中累积的带时间戳的EMSRP文件,只保留最新的一个,同时保留Response.csv和idle.csv不被处理。原代码虽然能运行,但长期来看存在几个潜在问题:比如用startswith('20')判断不够精准(可能误处理其他20开头的非目标文件)、没有过滤文件夹、缺乏异常处理(遇到权限问题或损坏文件会直接崩溃)、依赖字符串排序的可靠性(如果文件名格式有变动就会出错)。
这里给你一个更健壮、适合长期运行的实现方案:
import os import re from datetime import datetime SOURCE_FOLDER = 'E:/idle/' # 严格匹配目标文件名格式:yyyymmdd_EMSRP_yyymmdd_hhmmss.csv FILENAME_PATTERN = re.compile(r'^\d{8}_EMSRP_\d{8}_\d{6}\.csv$') def cleanup_old_emsrp_files(): emsrp_files = [] # 使用os.scandir比os.listdir更高效,且能直接获取文件属性 for entry in os.scandir(SOURCE_FOLDER): # 跳过子文件夹,只处理文件 if not entry.is_file(): continue # 直接跳过不需要处理的固定文件名 if entry.name in ('Response.csv', 'idle.csv'): continue # 用正则验证文件名格式,确保只处理目标文件 if FILENAME_PATTERN.match(entry.name): try: # 从文件名中提取时间戳并转换为datetime对象 timestamp_segment = entry.name.split('_')[-1].replace('.csv', '') file_datetime = datetime.strptime(timestamp_segment, '%Y%m%d_%H%M%S') emsrp_files.append((file_datetime, entry.path)) except ValueError: # 遇到格式不符合的文件直接跳过,避免程序崩溃 print(f"Skipping invalid EMSRP file: {entry.name}") continue # 按时间戳排序,最新的文件排在最后 emsrp_files.sort(key=lambda x: x[0]) # 只保留最新的一个,删除其余旧文件 if len(emsrp_files) > 1: for _, file_path in emsrp_files[:-1]: try: os.remove(file_path) print(f"Successfully deleted old file: {file_path}") except OSError as e: # 捕获删除时的系统异常(比如文件被占用、权限不足) print(f"Failed to delete {file_path}: {str(e)}") def main(): cleanup_old_emsrp_files() if __name__ == "__main__": main()
关键优化点说明:
- 精准的文件匹配:用正则表达式严格校验文件名格式,彻底避免误处理其他20开头的非目标文件
- 高效的文件遍历:
os.scandir比os.listdir性能更好,还能直接区分文件和文件夹,防止误删子文件夹 - 异常容错机制:捕获文件名解析错误和文件删除时的系统异常,单个文件的问题不会导致整个脚本崩溃,适合长期运行
- 可靠的排序逻辑:将文件名中的时间戳转换为
datetime对象排序,比单纯的字符串排序更可靠,也能应对未来可能的文件名格式微调 - 明确的文件排除:显式跳过
Response.csv和idle.csv,确保这两个文件永远不会被误处理
长期运行的额外建议:
- 可以把这个脚本配置成定时任务(Windows用任务计划程序,Linux/macOS用cron),定期自动执行清理
- 替换
print为logging模块,将清理操作和异常信息记录到日志文件,方便后续排查问题 - 可以添加一个参数,让脚本支持保留最新的N个文件(而不是固定1个),提升灵活性
内容的提问来源于stack exchange,提问作者Ninjasoup




