应优先使用 sha256 或 sha3_256 分块读取二进制文件校验,避免 md5 碰撞风险与大文件 oom;需确认文件写入完成、路径正确解析、跨系统比对强制 shallow=false,并警惕 filecmp.cmp() 的元数据与缓存缺陷。

用 hashlib 做基础校验,但别只算 md5
文件一致性最直接的判断方式就是哈希值比对,hashlib 是 Python 标准库里最常用的工具。不过只用 md5 有风险:它碰撞概率高,不适合安全敏感场景;而且小文件和大文件都用同一套逻辑读取,容易在大文件上 OOM。
- 优先选
sha256或sha3_256,抗碰撞性强,校验更可靠 - 必须分块读取,避免一次性
read()加载整个文件——尤其处理几百 MB 以上的日志或模型权重时 - 注意编码:校验二进制文件(如
.zip、.so)时,务必用'rb'模式打开,否则UnicodeDecodeError会直接中断
import hashlib
def file_sha256(path):
h = hashlib.sha256()
with open(path, 'rb') as f:
for chunk in iter(lambda: f.read(8192), b''):
h.update(chunk)
return h.hexdigest()
filecmp.cmp() 快但不总可信
filecmp.cmp() 看起来省事,但它默认不检查文件元数据,且在某些系统上会跳过内容比对(比如发现两个文件 size 不同就直接返回 False,但 size 相同却可能因缓存或挂载问题实际内容不同)。
- 加参数
shallow=False强制逐字节比对,否则可能漏掉硬链接或同名不同内容的情况 - 跨文件系统(比如从 NFS 挂载点比对本地文件)时,
shallow=True(默认)可能误判为相同,因为os.stat()返回的inode和mtime不可比 - 不适用于需要校验结果可复现的场景——它没有哈希输出,无法存档或跨环境验证
校验前先确认文件是否被截断或写入中
很多“校验失败”其实不是哈希问题,而是文件根本没写完。常见于日志轮转、模型导出、HTTP 下载未完成等场景。直接算哈希可能拿到半截内容,结果永远对不上。
- 检查
os.path.getsize()是否稳定:连续两次调用值一致,再开始校验 - Linux 下可用
lsof查看文件是否仍被进程占用写入(Python 里调用subprocess.run(['lsof', '-f', '--', path])),Windows 可尝试os.rename(path, path)看是否抛PermissionError - 如果文件由其他程序生成,优先等它显式释放锁(比如写完后 touch 一个
.done文件),而不是靠延时 sleep
多文件批量校验时,路径和编码容易出错
批量处理 glob.glob('*.bin') 或 os.listdir() 得到的文件列表,看似简单,但路径拼接错误、中文路径乱码、符号链接未解析等问题高频出现。
立即学习“Python免费学习笔记(深入)”;
- 永远用
pathlib.Path拼接路径,别用字符串+或os.path.join()混用斜杠——尤其在 Windows 上遇到\和/混杂时 - 遇到中文或 emoji 路径,确保终端和 Python 运行环境编码一致(多数情况是
utf-8),否则FileNotFoundError可能掩盖真实问题 - 用
path.resolve()展开符号链接,否则校验的是 link 本身而非目标文件,导致哈希值不匹配










