Python办公13:自动识别并删除电脑中的重复文件与大内存垃圾
2026/8/26 19:08:22 网站建设 项目流程

13:空间清理——自动识别并删除电脑中的重复文件与大内存垃圾

第二阶段:文件管理与系统自动化(9-15)

场景引入

C 盘红了?下载文件夹占了几十 GB?重复文件到处都是?

手动清理太慢且不彻底。本节教你用 Python 自动扫描:

  1. 找重复文件:基于 MD5 哈希值,精准识别内容完全相同的文件
  2. 找大文件:按大小排序,快速定位空间占用大户
  3. 清理临时文件:自动删除.tmp.log等垃圾文件

技术原理

重复文件检测

判断两个文件是否相同,有两种方式:

方法原理优点缺点
比大小比较文件大小超快大小相同≠内容相同
比哈希计算 MD5/SHA256 值100% 精准计算量大

最优策略:先按大小分组 → 同大小的文件再算哈希 → 减少不必要的计算。

扫描所有文件 ↓ 按文件大小分组 ↓ 同大小的文件计算 MD5 ↓ MD5 相同的即为重复文件

环境准备

pipinstallhashlib

hashlib是 Python 内置模块。


完整代码

importosimporthashlibfrompathlibimportPathfromcollectionsimportdefaultdict# ==================== 方案 1:查找重复文件 ====================deffind_duplicate_files(search_dir,min_size_mb=0):""" 查找目录中的重复文件(基于 MD5 哈希) 参数: search_dir: 搜索目录 min_size_mb: 最小文件大小(MB),忽略小于此值的文件 返回: 重复文件字典:{md5: [文件路径列表]} """search_path=Path(search_dir)min_size=min_size_mb*1024*1024# 第 1 步:按文件大小分组size_groups=defaultdict(list)print("正在扫描文件...")file_count=0forfile_pathinsearch_path.rglob('*'):iffile_path.is_file():size=file_path.stat().st_sizeifsize>=min_size:size_groups[size].append(str(file_path))file_count+=1print(f"扫描完成:{file_count}个文件")# 第 2 步:对同大小的文件计算 MD5hash_groups=defaultdict(list)forsize,filesinsize_groups.items():iflen(files)<2:continue# 只有一个文件,不可能重复forfile_pathinfiles:file_md5=calculate_md5(file_path)hash_groups[file_md5].append(file_path)# 第 3 步:筛选出重复的文件组duplicates={md5:pathsformd5,pathsinhash_groups.items()iflen(paths)>1}# 第 4 步:报告total_wasted=0formd5,pathsinduplicates.items():file_size=Path(paths[0]).stat().st_size wasted=file_size*(len(paths)-1)# 浪费的空间 = 单文件大小 × 重复数total_wasted+=wastedprint(f"\nMD5:{md5[:8]}... 大小:{file_size/1024:.1f}KB")forpinpaths:print(f" -{p}")print(f"\n{'='*50}")print(f"发现{len(duplicates)}组重复文件")print(f"可释放空间:{total_wasted/1024/1024:.2f}MB")returnduplicatesdefcalculate_md5(file_path,chunk_size=8192):"""计算文件的 MD5 哈希值"""md5=hashlib.md5()withopen(file_path,'rb')asf:whileTrue:chunk=f.read(chunk_size)ifnotchunk:breakmd5.update(chunk)returnmd5.hexdigest()# ==================== 方案 2:查找大文件 ====================deffind_large_files(search_dir,top_n=20,min_size_mb=10):""" 查找目录中最大的 N 个文件 参数: search_dir: 搜索目录 top_n: 返回最大的 N 个文件 min_size_mb: 最小文件大小(MB) """search_path=Path(search_dir)min_size=min_size_mb*1024*1024files=[]print("正在扫描大文件...")forfile_pathinsearch_path.rglob('*'):iffile_path.is_file():size=file_path.stat().st_sizeifsize>=min_size:files.append((str(file_path),size))# 按大小降序排序files.sort(key=lambdax:x[1],reverse=True)print(f"\n{'排名':<5}{'大小':<15}{'路径'}")print("-"*80)foridx,(path,size)inenumerate(files[:top_n],1):size_str=format_size(size)print(f"{idx:<5}{size_str:<15}{path}")returnfiles[:top_n]defformat_size(size_bytes):"""将字节数转为可读格式"""forunitin['B','KB','MB','GB','TB']:ifsize_bytes<1024:returnf"{size_bytes:.1f}{unit}"size_bytes/=1024# ==================== 方案 3:清理临时/垃圾文件 ====================defclean_temp_files(search_dir,dry_run=True):""" 清理临时文件和垃圾文件 参数: search_dir: 搜索目录 dry_run: True=预览,False=执行删除 """TEMP_EXTENSIONS={'.tmp','.temp','.log','.bak','.swp','.cache','.thumbs','.old','.original',}search_path=Path(search_dir)cleaned_count=0cleaned_size=0forfile_pathinsearch_path.rglob('*'):iffile_path.is_file()andfile_path.suffix.lower()inTEMP_EXTENSIONS:size=file_path.stat().st_size cleaned_size+=sizeifdry_run:print(f"[预览删除]{file_path}({format_size(size)})")else:try:file_path.unlink()print(f"[已删除]{file_path}({format_size(size)})")exceptPermissionError:print(f"[跳过-被占用]{file_path}")cleaned_count+=1print(f"\n{'='*50}")action="预览"ifdry_runelse"清理"print(f"{action}完成:{cleaned_count}个文件")print(f"可释放空间:{format_size(cleaned_size)}")# ==================== 使用示例 ====================if__name__=="__main__":TARGET_DIR=r"D:"# 方案 1:查找重复文件(忽略小于 1MB 的)# find_duplicate_files(TARGET_DIR, min_size_mb=1)# 方案 2:查找最大的 20 个文件(超过 10MB 的)find_large_files(TARGET_DIR,top_n=20,min_size_mb=10)# 方案 3:预览临时文件(不删除)# clean_temp_files(r"C:\Windows\Temp", dry_run=True)

代码逐行解析

1. MD5 分块计算

defcalculate_md5(file_path,chunk_size=8192):md5=hashlib.md5()withopen(file_path,'rb')asf:whileTrue:chunk=f.read(chunk_size)ifnotchunk:breakmd5.update(chunk)

不一次性读取整个文件,而是分块读取(8KB/次),这样即使是 GB 级大文件也不会撑爆内存。

2. 大小分组优化

forsize,filesinsize_groups.items():iflen(files)<2:continue# 跳过唯一大小的文件

只有大小相同的文件才可能重复。先过滤掉唯一的文件大小,大幅减少 MD5 计算量。

3. 空间统计

wasted=file_size*(len(paths)-1)

每组重复文件中,保留 1 份,其余都是浪费的空间。


进阶技巧

技巧 1:自动删除重复文件(保留最新的一份)

defdelete_duplicates(duplicates,keep='newest'):formd5,pathsinduplicates.items():# 按修改时间排序paths_with_time=[(p,Path(p).stat().st_mtime)forpinpaths]paths_with_time.sort(key=lambdax:x[1],reverse=(keep=='newest'))# 保留第一份,删除其余forpath,_inpaths_with_time[1:]:os.remove(path)print(f"已删除:{path}")

技巧 2:查找相似图片(感知哈希)

fromPILimportImageimportimagehashdefget_image_hash(image_path):img=Image.open(image_path)returnimagehash.phash(img)# 两张图片的哈希距离 < 5 认为是相似图片

常见问题

Q1:MD5 碰撞(两个不同文件有相同的 MD5)?

MD5 碰撞概率极低(约 2^64 分之一),对于日常文件清理完全足够。如需更高安全性,可改用 SHA256:

hashlib.sha256()

Q2:扫描速度太慢?

  • 使用min_size_mb过滤小文件
  • 排除不需要扫描的目录(如node_modules/
  • 只扫描特定类型文件

Q3:误删了重要文件?

使用dry_run=True先预览,确认后再执行实际删除。重要数据请先备份。


总结

清理策略函数效果
找重复find_duplicate_files()基于 MD5 精准去重
找大文件find_large_files()Top N 大文件排序
清垃圾clean_temp_files()删除临时/缓存文件

本节掌握了三种空间清理方法,帮助你快速释放磁盘空间。

下一节预告:14:压缩包处理——批量解压文件夹内的所有 ZIP/RAR 并自动分类!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询