You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python调用file.close()后文件仍被占用,邮件附件发送后移动文件报错求助

解决文件被占用导致shutil.move失败的问题

核心原因

邮件发送后,附件文件的句柄未被完全释放(比如SMTP连接未关闭、文件流未关闭),导致系统仍锁定该文件,无法执行移动操作。

解决方案

1. 确保文件流被正确关闭

添加附件时,必须用with语句打开文件,保证文件自动关闭,避免手动关闭遗漏:

with open(attachment_path, "rb") as attachment_file:
    part = MIMEBase('application', 'octet-stream')
    part.set_payload(attachment_file.read())
    encoders.encode_base64(part)
    part.add_header('Content-Disposition', f"attachment; filename={os.path.basename(attachment_path)}")
    msg.attach(part)

2. 显式关闭SMTP连接

发送邮件后,必须调用server.quit()或通过with语句管理SMTP连接,确保连接资源完全释放:

with smtplib.SMTP(smtp_server, smtp_port) as server:
    server.starttls()
    server.login(smtp_user, smtp_pass)
    server.sendmail(sender_email, receiver_email, msg.as_string())
    # 显式退出,强制释放所有关联资源
    server.quit()

3. 排查其他占用进程

如果以上操作仍无效,检查是否有杀毒软件、文件预览工具等第三方进程在访问目标文件,临时关闭这类工具后重试。

4. 临时延迟方案(不推荐,仅作应急)

若无法定位资源泄漏点,可在邮件发送完成后添加短暂延迟,给系统足够时间释放文件:

import time
# 邮件发送完成后
time.sleep(1)
shutil.move(attachment_path, archive_path)

完整示例代码

import smtplib
import os
import shutil
import time
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders

# 配置信息
smtp_server = "smtp.example.com"
smtp_port = 587
smtp_user = "your_email@example.com"
smtp_pass = "your_password"
sender_email = "your_email@example.com"
receiver_email = "target@example.com"
attachment_path = "test.txt"
archive_dir = "archive"
archived_filename = f"test_{time.strftime('%Y%m%d_%H%M%S')}.txt"
archive_path = os.path.join(archive_dir, archived_filename)

# 创建归档目录(如果不存在)
os.makedirs(archive_dir, exist_ok=True)

# 构建邮件
msg = MIMEMultipart()
msg['From'] = sender_email
msg['To'] = receiver_email
msg['Subject'] = "Test Email with Attachment"

# 添加附件(用with保证文件关闭)
with open(attachment_path, "rb") as attachment_file:
    part = MIMEBase('application', 'octet-stream')
    part.set_payload(attachment_file.read())
    encoders.encode_base64(part)
    part.add_header('Content-Disposition', f"attachment; filename={os.path.basename(attachment_path)}")
    msg.attach(part)

# 发送邮件并关闭连接
with smtplib.SMTP(smtp_server, smtp_port) as server:
    server.starttls()
    server.login(smtp_user, smtp_pass)
    server.sendmail(sender_email, receiver_email, msg.as_string())
    server.quit()

# 移动文件
shutil.move(attachment_path, archive_path)

内容的提问来源于stack exchange,提问作者kashif ashraf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 10:01:22