用 Python 找出重复文件
先按大小筛选,再分块计算摘要,生成只读报告。
适用环境:Python 3.10+;普通静态文件目录
为什么不能只比较名称
两份内容相同的文件可以有不同名字,两份同名文件也可以完全不同。可靠的第一步是比较大小;大小不同便无需继续。大小相同的文件再计算内容摘要,可以减少大目录中的无用读取。
准备一个小测试目录
新建 sample_files 文件夹,放入两份内容相同但名字不同的文件,再放一份内容不同的文件。把下面代码保存为 duplicate_files.py,与 sample_files 放在同一目录,先在这个小范围验证。
完整脚本
from pathlib import Path
from collections import defaultdict
import hashlib
root = Path('sample_files')
by_size = defaultdict(list)
for path in root.rglob('*'):
if path.is_symlink() or not path.is_file():
continue
by_size[path.stat().st_size].append(path)
for size, paths in by_size.items():
if len(paths) < 2:
continue
by_hash = defaultdict(list)
for path in paths:
try:
digest = hashlib.sha256()
with path.open('rb') as stream:
for block in iter(lambda: stream.read(1024 * 1024), b''):
digest.update(block)
by_hash[digest.hexdigest()].append(path)
except OSError as exc:
print('跳过无法读取的文件:', path, exc)
for matches in by_hash.values():
if len(matches) > 1:
print('\n相同内容,文件大小:', size)
for path in matches:
print(path)运行与判断结果
python duplicate_files.py输出应把两份相同文件列在同一组,不同内容不应被归到一起。脚本只列出结果,没有删除逻辑。1 MiB 分块读取避免一次性把大文件装进内存;文件路径列表仍会占内存,因此不适合直接扫描无限大的目录树。
实际使用的限制
修改 root 后先确认范围,不要直接指向整个系统盘。文件在扫描过程中变化、权限不足或网络盘暂时不可用都可能影响结果;初始目录遍历的异常可能终止运行,应根据报错缩小范围。摘要相同足以用于通常的去重初筛,重要资料删除前仍需人工核实用途和备份。