AI辅助开发三款Python磁盘清理脚本,定位临时文件、大文件与重复文件

发布时间:2026/9/4 22:12:42
AI辅助开发三款Python磁盘清理脚本,定位临时文件、大文件与重复文件 把“清理硬盘空间”这件事想简单了的人往往还没有经历过真实环境系统 Temp 目录里堆着几个月前安装包留下的缓存下载文件夹中躺着一两个体积惊人的虚拟磁盘镜像备份盘里同一份照片出现多个副本。手工删除不仅费时而且一旦清理逻辑不清晰很容易把不该删的文件顺手删掉。这篇文章要分享的内容也和硬盘清理有关只不过名字有点特殊“三连发但都不是人写的”。更准确地说这三款硬盘清理小工具都是借助 AI 编程助手生成初版代码再由人工做安全审查、目录过滤与参数调整后得到的可执行脚本。三个人各自解决一个不同的磁盘占用问题临时文件清理、大文件定位、重复文件检测。代码都使用 Python 标准库编写不依赖第三方 GUI也不包含任何隐藏的“全家桶”安装逻辑。如果你正在为 C 盘爆红发愁或者想体验一下“用 AI 辅助开发工具类脚本”的完整工作流这篇文章会比较合适。1. 为什么要做三款硬盘清理工具1.1 从一次“系统盘变红”的现实场景说起Windows 系统盘剩余空间不足时任务栏会频繁出现红条提示软件更新失败、浏览器缓存写入异常、IDE 索引无法生成各种问题会接连出现。很多人第一反应是打开“磁盘清理”勾选“临时文件”后点击清理。这个动作确实有用但往往只能解决一部分问题。更常见的场景是这样的下载目录中保留了十几个不同版本的安装包Python 项目构建时留下的.pyc缓存和__pycache__目录旧项目里为了排查问题而复制出来的日志文件开发工具在用户目录下悄悄写入的索引和缓存。这些东西不会出现在系统自带的清理列表里也不会被常规“垃圾清理”软件完整覆盖。这就需要一个更灵活的清理工具能自己指定扫描范围、自己定义过期时间、自己决定是否执行删除。而这类“自定义的清理脚本”并不复杂却非常值得沉淀成工具避免每次都重复排查。1.2 “都不是人写的”到底指什么标题里的“都不是人写的”并不是指工具没有人开发而是指这三份代码的初版并非由开发者逐行手写而是由 AI 编程助手根据需求描述生成再由人工审查、修改和补充边界逻辑。这种开发方式在脚本型工具中非常实用。AI 编程助手有一个天然优势它可以快速把一个“功能描述”翻译成 Python 代码。例如“写一个扫描当前目录下大文件的脚本”它能立刻生成一个可运行的版本。但 AI 生成的代码有一个明显短板它不一定理解你的真实使用场景也不一定了解你所在环境的目录权限、命名习惯和安全边界。如果直接把 AI 输出的代码放到生产环境运行风险相当大。所以真正落地的流程应当是使用 AI 生成初版脚本人工理解脚本逻辑补充 dry-run 演练模式明确“默认不删除任何文件”最后在小范围目录中验证再放到真实环境中使用。标题表面在说“不是人写的”实际上是在讲“AI 负责生成人负责审查”的新协作方式。1.3 这三款工具分别解决什么问题工具名称解决的核心问题典型场景cleanup_tmp.py临时目录与缓存文件积累Temp 目录占用过大、安装包残留find_big_files.py无法快速定位大文件在哪磁盘空间告警需要找到 Top 大文件find_duplicates.py同一份文件在多个目录重复存放备份文件重复、照片视频出现多份副本这三款工具不是替代品而是互补关系。实际排查磁盘空间时建议先运行第二款工具找出大文件再运行第三款工具检查重复文件最后用第一款工具清理超过指定天数的临时文件。扫描和删除分开执行可以避免误删。2. 环境准备与项目目录规划2.1 运行环境版本要求本文示例以 Windows 11 Python 3.10 为主要环境同时兼容 Windows 10、Linux 和 macOS。三个脚本全部使用 Python 标准库不需要额外安装 requests、pandas 等第三方依赖因此对 Python 版本的要求也不高Python 3.8 以上基本都能运行。如果你的电脑还没有安装 Python可以先到 Python 官网下载安装包。安装时务必勾选“Add Python to PATH”方便在命令行中直接使用python命令。如果安装的是 Python 3.12 等更新版本脚本逻辑也不需要改动。需要注意一点不同 AI 编程助手生成的代码风格会有差异版本要求也可能不同。因此在生成脚本时最好在提示词中写明目标平台和 Python 版本。例如“请用 Python 编写一个命令行脚本目标平台是 Windows 11Python 版本是 3.10”这样能减少兼容问题。2.2 建议的项目目录结构为了便于管理和后续扩展建议把三款工具放在同一个目录下disk-cleaner-ai/ ├── cleanup_tmp.py ├── find_big_files.py ├── find_duplicates.py └── README.mdREADME.md不是必需文件但建议记录每个脚本的功能、运行参数和已知风险。如果后续让 AI 继续迭代代码这些记录会变成非常有价值的上下文帮助 AI 快速理解之前的设计决策。在写作本文前我建议你单独准备一个测试目录例如D:/clean_test在测试目录中创建一些临时文件和大文件。先在这个目录里反复 dry-run确认无误后再把扫描对象切到真实目录。2.3 运行前必须明确的安全边界磁盘清理工具和普通代码不同它一旦真正执行删除操作就是不可逆的。即使删除后使用数据恢复工具也不能保证 100% 找回。因此在运行任何清理类脚本前必须先明确几条红线第一默认永远使用 dry-run 模式。所谓 dry-run就是“演练模式”脚本只扫描、统计并打印将要做的事情但不真正删除。只有用户明确加入类似--delete的参数后脚本才执行删除。把删除开关设计为“主动加入”而不是“默认开启”能最大程度避免误操作。第二不要对系统关键目录做无差别清理。例如C:/Windows/System32、C:/Program Files这类目录不建议交给通用清理脚本扫描删除。脚本扫描范围应当限定在临时目录、缓存目录、用户下载目录等明确安全的范围内。第三扫描结果不等于删除名单。脚本输出“发现多少个文件”只是第一步真正删除前应当用人工或白名单机制再确认一遍。尤其在删除重复文件时要知道保留哪一个路径下的副本。3. 清理类工具的共同套路与提示词设计3.1 磁盘清理背后的操作模型不管是临时文件清理、大文件定位还是重复文件检测它们的底层逻辑都有相似之处遍历目录 → 收集文件属性 → 判断条件 → 输出结果。临时文件清理多了“删除”动作大文件定位多了“排序”过程重复文件检测则多了一次“内容哈希计算”。把清理任务抽象成这个流程非常有利于和 AI 协作。因为 AI 很难在没有约束的情况下一次生成完美代码但如果你把步骤拆清楚它生成的代码质量会明显提升。一次典型的目录扫描至少需要处理以下问题目录不存在时怎么办遇到权限不足的目录是终止还是跳过文件被占用导致删除失败时怎么处理扫描大目录时如何避免重复遍历符号链接。这些问题里“权限”和“文件被占用”是 Windows 环境最常见的两个异常点AI 往往能写出 try-except但选择忽略哪些异常、在哪里忽略则需要人工确认。3.2 如何向 AI 描述清理需求一个“能跑”的清理脚本提示词至少应当包含五类信息目标平台与语言版本、输入参数、扫描范围、输出形式、安全边界。下面以临时文件清理器为例给出一段可以直接使用的提示词模板请用 Python 写一个临时文件清理脚本目标平台是 Windows 11。 需求如下 1. 默认扫描系统临时目录同时支持通过 --dirs 参数传入多个自定义目录 2. 只清理最后修改时间早于 --days 天数的文件默认值是 7 天 3. 默认不执行删除只有带上 --delete 参数时才真正删除文件 4. 删除前打印每个文件的路径、文件大小以及总计可释放空间 5. 遍历时遇到文件占用的错误或权限错误跳过并记录不要中断程序 6. 只使用 Python 标准库实现。这段描述中最重要的是第 3 条。如果没有把“默认不执行删除”写清楚AI 很可能生成一个默认直接删除的脚本。这类脚本在测试环境中看不出问题一旦放到真实 Temp 目录下执行后果无法估计。3.3 AI 生成代码后的人工检查顺序拿到 AI 生成的代码后不要急着直接运行。建议按照下面的顺序做一次代码审查先看命令行参数解析部分确认“默认操作”是否安全再看目录遍历方式确认是否使用了递归遍历、是否可能形成循环然后看文件筛选条件确保删除逻辑只作用于符合条件的普通文件最后看异常处理范围判断 catch 到的异常是不是太宽泛。代码审查能力是使用 AI 编程助手过程中最值得提升的技能。很多时候AI 给出的代码初版已经覆盖了 80% 的主流程剩下 20% 的安全边界与异常分支需要人来补充。这三款硬盘清理工具的代码也会在实际项目中反复调整。4. 第一发临时文件与过期缓存清理器4.1 需求要点第一款工具解决的是“临时文件越积越多”的问题。Windows 临时目录通常存储在%TEMP%环境变量中不同用户的 Temp 路径不同因此脚本不能把路径写死而应该通过环境变量读取。清理临时文件时不能一刀切。有些文件虽然位于 Temp 目录但可能正在被某个程序使用删除时会抛出 PermissionError。还有些文件是最近几分钟刚生成的大概率还在被使用清理它们的意义不大。因此第一版工具增加了两个条件只处理最后修改时间早于--days天数的文件遇到文件被占用或权限问题时跳过。4.2 完整代码cleanup_tmp.py#!/usr/bin/env python3 # -*- coding: utf-8 -*- 临时文件清理小工具 功能 - 扫描指定目录或系统 Temp 目录 - 找出最后修改时间早于指定天数的文件 - 默认只打印结果不执行删除 - 只有传入 --delete 参数时才真正删除文件 用法示例 python cleanup_tmp.py --days 7 python cleanup_tmp.py --dirs D:/clean_test --days 7 python cleanup_tmp.py --days 7 --delete import argparse import os import time from pathlib import Path def parse_args(): parser argparse.ArgumentParser(description临时文件清理工具) parser.add_argument( --dirs, nargs*, defaultNone, help要扫描的目录可传入多个默认使用系统临时目录, ) parser.add_argument( --days, typeint, default7, help只清理最后修改时间早于 N 天的文件默认 7 天, ) parser.add_argument( --delete, actionstore_true, help加入该参数后才会真正删除文件默认只做演练, ) return parser.parse_args() def get_default_temp_dirs(): 从系统环境变量中获取临时目录。 temp_dir os.environ.get(TEMP) if temp_dir: return [Path(temp_dir)] return [Path.home() / AppData / Local / Temp] def collect_expired_files(dirs, cutoff_ts, exclude_dirsNone): 遍历目录找出最后修改时间早于 cutoff_ts 的普通文件。 返回列表每个元素为 (文件路径, 文件大小, 最后修改时间)。访问失败的文件直接跳过。 if exclude_dirs is None: exclude_dirs {.git, $RECYCLE.BIN, System Volume Information} candidates [] for base_dir in dirs: base_dir Path(base_dir).expanduser().resolve() if not base_dir.exists(): print(f[跳过] 目录不存在: {base_dir}) continue for dirpath, dirnames, filenames in os.walk(base_dir): # 删除目标列表不进入这些子目录避免碰到系统和回收站目录 dirnames[:] [d for d in dirnames if d not in exclude_dirs] for filename in filenames: file_path Path(dirpath) / filename try: stat_info file_path.stat() if stat_info.st_mtime cutoff_ts: candidates.append( (file_path, stat_info.st_size, stat_info.st_mtime) ) except (PermissionError, FileNotFoundError, OSError): continue return candidates def format_size(size_bytes): 将字节数格式化为便于阅读的字符串。 if size_bytes 1024 * 1024 * 1024: return f{size_bytes / (1024 * 1024 * 1024):.2f} GB if size_bytes 1024 * 1024: return f{size_bytes / (1024 * 1024):.2f} MB if size_bytes 1024: return f{size_bytes / 1024:.2f} KB return f{size_bytes} B def main(): args parse_args() dirs [Path(d) for d in args.dirs] if args.dirs else get_default_temp_dirs() cutoff_ts time.time() - args.days * 24 * 60 * 60 print(f扫描目录: {, .join(str(d) for d in dirs)}) print(f清理阈值: {args.days} 天前被修改的文件) print() candidates collect_expired_files(dirs, cutoff_ts) total_count len(candidates) total_size sum(size for _, size, _ in candidates) if total_count 0: print(没有找到符合条件的文件无需清理。) return print(f共发现 {total_count} 个候选文件预计释放 {format_size(total_size)}) print(以下是占用空间最大的 15 个候选文件) candidates_sorted sorted(candidates, keylambda item: item[1], reverseTrue) for file_path, size, mtime in candidates_sorted[:15]: time_str time.strftime(%Y-%m-%d %H:%M:%S, time.localtime(mtime)) print(f {format_size(size):10} {time_str} {file_path}) if not args.delete: print() print(当前为演练模式dry-run未删除任何文件。) print(确认无误后可加上 --delete 参数执行真正的清理。) return deleted_count 0 deleted_size 0 print() print(开始执行删除...) for file_path, size, _ in candidates: try: file_path.unlink(missing_okTrue) deleted_count 1 deleted_size size print(f[已删除] {file_path}) except PermissionError: print(f[跳过] 文件被占用或无权限: {file_path}) except OSError as exc: print(f[跳过] 删除失败: {file_path}错误: {exc}) print() print(f清理完成共删除 {deleted_count} 个文件释放 {format_size(deleted_size)}。) if __name__ __main__: main()4.3 参数与运行方式说明在正式运行前先用命令行查看帮助信息python cleanup_tmp.py --help帮助信息中可以看到三个关键参数--dirs用于指定要扫描的目录可传入多个路径以空格分隔--days用于设置文件过期天数--delete是真正的删除开关不加这个参数时脚本只做扫描和统计。一个比较安全的执行方式是先演练再确认python cleanup_tmp.py --days 7 python cleanup_tmp.py --days 7 --delete第二条命令只有在第一条命令的输出结果看起来没有问题时才执行。执行完成后脚本会打印“共删除多少文件、释放多少空间”这些信息可以作为操作留痕方便后续排查。4.4 这段代码为什么这样设计代码中有一个容易被忽略的细节遍历目录时使用了os.walk(base_dir)并通过dirnames[:] [...]修改子目录列表从而跳过.git、$RECYCLE.BIN这类目录。如果不跳过回收站目录脚本可能会尝试清理回收站中的文件而 Windows 回收站有一套自己的文件命名和权限体系清理逻辑不当容易影响回收站恢复功能。删除时使用file_path.unlink(missing_okTrue)这个 API 在文件已被其他进程删除时不会抛出 FileNotFoundError。不过文件被占用时仍会抛出 PermissionError所以删除逻辑中专门捕获了这个异常并打印“跳过”不会让整个脚本中断。5. 第二发大文件定位器5.1 使用场景与实现思路临时文件清理只能解决“目录臃肿”的问题但很多时候磁盘空间的真正大头是某一个 GB 级别的文件。要找到这个大文件不能靠肉眼逐个目录翻看最直接的方法是扫描整个目录树统计每个文件的大小再按大小降序排列输出 Top N。这款大文件定位器的目标很简单指定一个根目录列出该目录下体积超过阈值的文件。脚本不会删除任何文件输出内容只做定位参考。在此基础上加入--top参数控制输出数量加入--min-size参数控制最小体积阈值避免输出太多无意义的小文件。5.2 完整代码find_big_files.py#!/usr/bin/env python3 # -*- coding: utf-8 -*- 大文件定位器 功能 - 递归扫描指定目录 - 列出文件大小大于等于阈值的大文件 - 按文件大小降序输出 Top N 用法示例 python find_big_files.py D:/Downloads python find_big_files.py D:/Downloads --min-size 200MB --top 30 python find_big_files.py . --min-size 1GB import argparse import os import time from datetime import datetime from pathlib import Path def parse_size(size_text): 将 100MB、1GB、500KB 这类文本解析成字节数默认按 MB 处理。 size_text size_text.strip().upper() if size_text.endswith(KB): return int(float(size_text[:-2]) * 1024) if size_text.endswith(MB): return int(float(size_text[:-2]) * 1024 * 1024) if size_text.endswith(GB): return int(float(size_text[:-2]) * 1024 * 1024 * 1024) try: # 没有单位时按 MB 处理例如 100 表示 100MB return int(float(size_text) * 1024 * 1024) except ValueError: raise argparse.ArgumentTypeError(f无法解析大小参数: {size_text}) def scan_large_files(root_dir, min_size): 扫描 root_dir 下的普通文件返回大小大于等于 min_size 的文件列表。 返回列表元素为 (文件路径, 文件大小, 最后修改时间戳)。 result [] for dirpath, dirnames, filenames in os.walk(root_dir): # 跳过 Windows 系统卷信息目录和回收站目录 dirnames[:] [ d for d in dirnames if not d.startswith($) and d not in {System Volume Information, Recovery} ] for filename in filenames: file_path Path(dirpath) / filename try: stat_info file_path.stat() if stat_info.st_size min_size: result.append( (file_path, stat_info.st_size, stat_info.st_mtime) ) except (PermissionError, FileNotFoundError, OSError): continue result.sort(keylambda item: item[1], reverseTrue) return result def format_size(size_bytes): if size_bytes 1024 * 1024 * 1024: return f{size_bytes / (1024 * 1024 * 1024):.2f} GB if size_bytes 1024 * 1024: return f{size_bytes / (1024 * 1024):.2f} MB if size_bytes 1024: return f{size_bytes / 1024:.2f} KB return f{size_bytes} B def main(): parser argparse.ArgumentParser(description扫描目录并定位大文件) parser.add_argument( root, nargs?, default., help要扫描的根目录默认当前目录, ) parser.add_argument( --min-size, typeparse_size, default100MB, help文件大小阈值例如 200MB、1GB、500KB默认 100MB, ) parser.add_argument( --top, typeint, default20, help只输出体积最大的前 N 个文件默认 20, ) args parser.parse_args() root_dir Path(args.root).expanduser().resolve() if not root_dir.exists(): print(f错误目录不存在{root_dir}) return print(f正在扫描目录: {root_dir}) print(f文件大小阈值: {format_size(args.min_size)}) start_time time.time() large_files scan_large_files(root_dir, args.min_size) elapsed time.time() - start_time print(f扫描完成耗时 {elapsed:.2f} 秒共发现 {len(large_files)} 个大文件。) if not large_files: print(未发现超过阈值的文件。) return print(f\n体积最大的 {min(args.top, len(large_files))} 个文件如下) for rank, (file_path, size, mtime) in enumerate( large_files[: args.top], start1 ): mod_time datetime.fromtimestamp(mtime).strftime(%Y-%m-%d %H:%M:%S) print(f{rank:3}. {format_size(size):10} {mod_time} {file_path}) if __name__ __main__: main()5.3 运行示例与结果解读假设要扫描D:/Downloads目录只关心大于 200MB 的文件按体积输出前 20 个python find_big_files.py D:/Downloads --min-size 200MB --top 20扫描结果中每一行会依次显示排名、文件大小、最后修改时间、完整路径。定位到大文件后不要马上删除而是先确认这个文件是否属于某个仍然在使用的软件。例如虚拟磁盘镜像文件可能被虚拟机正在使用日志文件可能正被后台服务写入这些情况下直接删除会导致程序异常。6. 第三发重复文件检测器6.1 为什么重复文件很难人工排查重复文件往往隐藏在多个目录层级中。比如“照片备份”目录下有一份原始照片桌面上又复制了一份用于发送给朋友下载目录里一个安装包出现了两个版本文件名略有不同但内容完全一致。人工排查时如果只看文件名很难判断内容是否相同。更可靠的方法是计算文件内容的哈希值。哈希值可以简单理解成文件的“内容指纹”只要两个文件内容完全一致计算出的 MD5 值就相同。不过全盘范围两两比较哈希值性能很低。因此重复文件检测通常采用“两步筛选”第一步先按文件大小分组只把大小相同的文件放到一组第二步再对同一组内的文件计算 MD5。由于真正内容的重复概率远大于刚好同大小但内容不同的情况这种方式能大幅减少哈希计算量。6.2 完整代码find_duplicates.py#!/usr/bin/env python3 # -*- coding: utf-8 -*- 重复文件检测器 功能 - 扫描指定目录 - 先按文件大小分组再对候选文件计算 MD5 - 找出内容完全一致的文件组并输出 用法示例 python find_duplicates.py D:/backup python find_duplicates.py D:/backup --min-size 1MB import argparse import hashlib import os from collections import defaultdict from datetime import datetime from pathlib import Path