场景引入
c 盘红了?下载文件夹占了几十 gb?重复文件到处都是?
手动清理太慢且不彻底。本节教你用 python 自动扫描:
- 找重复文件:基于 md5 哈希值,精准识别内容完全相同的文件
- 找大文件:按大小排序,快速定位空间占用大户
- 清理临时文件:自动删除
.tmp、.log等垃圾文件
技术原理
重复文件检测
判断两个文件是否相同,有两种方式:
| 方法 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 比大小 | 比较文件大小 | 超快 | 大小相同≠内容相同 |
| 比哈希 | 计算 md5/sha256 值 | 100% 精准 | 计算量大 |
最优策略:先按大小分组 → 同大小的文件再算哈希 → 减少不必要的计算。
扫描所有文件
↓
按文件大小分组
↓
同大小的文件计算 md5
↓
md5 相同的即为重复文件
环境准备
pip install hashlib
hashlib 是 python 内置模块。
完整代码
import os
import hashlib
from pathlib import path
from collections import defaultdict
# ==================== 方案 1:查找重复文件 ====================
def find_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 = 0
for file_path in search_path.rglob('*'):
if file_path.is_file():
size = file_path.stat().st_size
if size >= min_size:
size_groups[size].append(str(file_path))
file_count += 1
print(f"扫描完成: {file_count} 个文件")
# 第 2 步:对同大小的文件计算 md5
hash_groups = defaultdict(list)
for size, files in size_groups.items():
if len(files) < 2:
continue # 只有一个文件,不可能重复
for file_path in files:
file_md5 = calculate_md5(file_path)
hash_groups[file_md5].append(file_path)
# 第 3 步:筛选出重复的文件组
duplicates = {md5: paths for md5, paths in hash_groups.items() if len(paths) > 1}
# 第 4 步:报告
total_wasted = 0
for md5, paths in duplicates.items():
file_size = path(paths[0]).stat().st_size
wasted = file_size * (len(paths) - 1) # 浪费的空间 = 单文件大小 × 重复数
total_wasted += wasted
print(f"\nmd5: {md5[:8]}... 大小: {file_size / 1024:.1f} kb")
for p in paths:
print(f" - {p}")
print(f"\n{'='*50}")
print(f"发现 {len(duplicates)} 组重复文件")
print(f"可释放空间: {total_wasted / 1024 / 1024:.2f} mb")
return duplicates
def calculate_md5(file_path, chunk_size=8192):
"""计算文件的 md5 哈希值"""
md5 = hashlib.md5()
with open(file_path, 'rb') as f:
while true:
chunk = f.read(chunk_size)
if not chunk:
break
md5.update(chunk)
return md5.hexdigest()
# ==================== 方案 2:查找大文件 ====================
def find_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 * 1024
files = []
print("正在扫描大文件...")
for file_path in search_path.rglob('*'):
if file_path.is_file():
size = file_path.stat().st_size
if size >= min_size:
files.append((str(file_path), size))
# 按大小降序排序
files.sort(key=lambda x: x[1], reverse=true)
print(f"\n{'排名':<5} {'大小':<15} {'路径'}")
print("-" * 80)
for idx, (path, size) in enumerate(files[:top_n], 1):
size_str = format_size(size)
print(f"{idx:<5} {size_str:<15} {path}")
return files[:top_n]
def format_size(size_bytes):
"""将字节数转为可读格式"""
for unit in ['b', 'kb', 'mb', 'gb', 'tb']:
if size_bytes < 1024:
return f"{size_bytes:.1f} {unit}"
size_bytes /= 1024
# ==================== 方案 3:清理临时/垃圾文件 ====================
def clean_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 = 0
cleaned_size = 0
for file_path in search_path.rglob('*'):
if file_path.is_file() and file_path.suffix.lower() in temp_extensions:
size = file_path.stat().st_size
cleaned_size += size
if dry_run:
print(f"[预览删除] {file_path} ({format_size(size)})")
else:
try:
file_path.unlink()
print(f"[已删除] {file_path} ({format_size(size)})")
except permissionerror:
print(f"[跳过-被占用] {file_path}")
cleaned_count += 1
print(f"\n{'='*50}")
action = "预览" if dry_run else "清理"
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 分块计算
def calculate_md5(file_path, chunk_size=8192):
md5 = hashlib.md5()
with open(file_path, 'rb') as f:
while true:
chunk = f.read(chunk_size)
if not chunk:
break
md5.update(chunk)
不一次性读取整个文件,而是分块读取(8kb/次),这样即使是 gb 级大文件也不会撑爆内存。
2. 大小分组优化
for size, files in size_groups.items():
if len(files) < 2:
continue # 跳过唯一大小的文件
只有大小相同的文件才可能重复。先过滤掉唯一的文件大小,大幅减少 md5 计算量。
3. 空间统计
wasted = file_size * (len(paths) - 1)
每组重复文件中,保留 1 份,其余都是浪费的空间。
进阶技巧
技巧 1:自动删除重复文件(保留最新的一份)
def delete_duplicates(duplicates, keep='newest'):
for md5, paths in duplicates.items():
# 按修改时间排序
paths_with_time = [(p, path(p).stat().st_mtime) for p in paths]
paths_with_time.sort(key=lambda x: x[1], reverse=(keep == 'newest'))
# 保留第一份,删除其余
for path, _ in paths_with_time[1:]:
os.remove(path)
print(f"已删除: {path}")
技巧 2:查找相似图片(感知哈希)
from pil import image
import imagehash
def get_image_hash(image_path):
img = image.open(image_path)
return imagehash.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() | 删除临时/缓存文件 |
到此这篇关于python实现自动识别并清理电脑c盘的垃圾文件的文章就介绍到这了,更多相关python清理电脑垃圾文件内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论