Python中shutil.move遇.filepart后缀文件找不到的问题排查与解决
问题原因及解决方法
原因分析
- 文件句柄未及时释放:你代码中直接将
open(event.src_path,'rb')生成的文件对象传入requests,虽然requests会在请求结束后尝试关闭文件,但存在异常场景或垃圾回收延迟的情况,导致文件句柄长时间未释放。此时文件处于被占用状态,部分文件工具(如下载器、监控工具)会保留.filepart临时后缀,或在文件可用后自动重命名为正式文件名,后续执行shutil.move时就会找不到原.filepart文件。 - 文件句柄泄漏风险:这种直接open不手动关闭的写法,在高频操作下会引发句柄泄漏,进一步加剧文件占用问题,导致系统无法正确识别文件状态。
解决方法
方法1:使用with语句管理文件(推荐)
with语句会在代码块结束后自动关闭文件,无论请求成功或失败,都能确保文件句柄及时释放:
payload = {} # 你的payload内容 url = "你的API地址" headers = {} with open(event.src_path, 'rb') as file_obj: files = [ ('nzb_file', (nzbTitle, file_obj, 'application/octet-stream')) ] response = requests.request("POST", url, headers=headers, data=payload, files=files) # 后续执行移动操作 if response.status_code == 200: shutil.move(event.src_path, "成功目录路径") else: shutil.move(event.src_path, "其他目录路径")
方法2:手动关闭文件句柄
如果不想用with,可以在请求完成后手动关闭文件对象,确保资源释放:
payload = {} # 你的payload内容 url = "你的API地址" headers = {} files = [ ('nzb_file', (nzbTitle, open(event.src_path,'rb'), 'application/octet-stream')) ] try: response = requests.request("POST", url, headers=headers, data=payload, files=files) finally: # 遍历files列表,关闭所有文件对象 for field_name, (file_name, file_obj, content_type) in files: file_obj.close() # 后续移动操作 if response.status_code == 200: shutil.move(event.src_path, "成功目录路径") else: shutil.move(event.src_path, "其他目录路径")
额外检查
确认你的文件监控触发逻辑是否合理,确保只在文件完全写入完成(即.filepart后缀已被移除,文件处于稳定状态)时才触发上传流程,避免在文件还处于临时状态时就开始处理。
内容的提问来源于stack exchange,提问作者Peter Glad
相关产品推荐
相关产品推荐

