应先用 os.path.exists 和 os.path.isfile 双重确认文件存在且为普通文件,再结合 os.path.getmtime 判断修改时间是否超过阈值(如30分钟),避免删除正在被占用的临时文件。

os.remove 报错 FileNotFoundError 怎么办
os.remove 直接删文件时,如果文件已被其他进程占用、路径不存在或权限不足,会抛 FileNotFoundError 或 PermissionError。这不是代码写错了,而是清理逻辑没兜住现实情况。
- 删之前必须先用
os.path.exists和os.path.isfile双重确认目标是真实存在的普通文件 - 不要依赖
try/except FileNotFoundError做主判断——它掩盖了“本不该删却去删”的逻辑错误 - Windows 下尤其注意:下载工具(如 Chrome、迅雷)可能在文件名后加临时后缀(如
.crdownload),但对应文件句柄未释放,此时os.remove必然失败
if os.path.exists(filepath) and os.path.isfile(filepath):
try:
os.remove(filepath)
except (PermissionError, OSError):
# 记录日志,跳过,不中断整个清理流程
pass
怎么判断“该删的临时文件”
临时下载目录里混着正在写的文件、刚下完还没关句柄的文件、以及真正废弃的旧文件。靠文件名后缀(如 .tmp、.part)只能筛一部分,关键得看修改时间 + 当前状态。
- 用
os.path.getmtime获取最后修改时间,和当前时间比对;别用os.path.getctime,Windows 上它是创建时间,Linux 上无定义 - 建议设一个保守阈值,比如“30 分钟内修改过的文件一律跳过”,而不是“1 小时以上才删”——因为有些下载器会持续更新 mtime 直到完全结束
- 注意时区:所有时间比较统一用
time.time()(秒级时间戳),避免datetime对象跨时区转换出错
示例逻辑:
cutoff = time.time() - 30 * 60 # 30分钟前
for fname in os.listdir(download_dir):
filepath = os.path.join(download_dir, fname)
if os.path.isfile(filepath):
try:
if os.path.getmtime(filepath) <h3>shutil.rmtree vs os.remove:删整个目录时别手滑</h3><p>如果目标是清空整个临时下载目录(而非只删其中文件),有人会直接上 <code>shutil.rmtree</code>。这很危险——路径拼错、变量为空、符号链接没处理,都会导致误删。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill5288" title="提示词大师-python版"><img
src="https://img.php.cn/upload/skill/000/000/081/179042051830184.jpg" alt="提示词大师-python版" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill5288" title="提示词大师-python版" class="overflowclass">提示词大师-python版</a>
<p class="overflowclass">图片提示词生成器?不止如此。
马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。
用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。
用得越多,它越快:缓存机制让后续对话越来越省。
RAG进化:成功案例持续入库,越跑越聪明。
输入「新手指南」查看完整功能介绍</p>
</div>
<a rel="nofollow" href="/xiazai/skill5288" title="提示词大师-python版" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
-
shutil.rmtree不检查路径是否为目录,也不做任何确认,删错就是永久丢失 - 更安全的做法是:先
os.path.isdir确认,再逐个os.remove文件 +os.rmdir子目录,保留控制粒度 - 如果真要用
shutil.rmtree,务必加白名单校验:比如只允许路径以/tmp/downloads_开头,且不含..字符串
容易踩的坑:
-
shutil.rmtree('downloads')和shutil.rmtree('./downloads')在不同工作目录下行为不一致 - 路径末尾带斜杠(如
'downloads/')在某些系统上可能绕过isdir检查 - 符号链接指向系统目录时,
rmtree会顺着链接进去删,不是删链接本身
定时执行时权限与用户上下文最常被忽略
脚本手动跑通了,放进 cron 或 Windows 任务计划程序就失败,90% 是因为运行身份变了。
- Linux 下 cron 默认没有
$HOME、$PATH,os.chdir或相对路径会失效;必须用绝对路径,比如/home/user/downloads而非~/downloads - Windows 服务模式运行 Python 脚本时,默认没 GUI 会话,无法访问网络驱动器映射(如
Z:\),得改用 UNC 路径(如\server\share) - macOS 的 launchd 有 sandbox 限制,访问
~/Downloads需显式声明权限,否则os.listdir直接返回空
验证方式很简单:在定时任务里加一行日志,打印 os.getcwd()、os.environ.get('USER') 和 os.listdir(download_dir) 结果,别猜。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










