不能直接用hashlib.md5(file.read()),因为会将大文件一次性加载进内存引发memoryerror;正确做法是用rb模式分块读取(如8192字节)并调用update()增量计算,最后用hexdigest()获取结果。

为什么不能直接用 hashlib.md5(file.read())
因为大文件(比如几个GB)会一次性加载进内存,极易触发 MemoryError 或拖慢整个系统。MD5 是流式算法,根本不需要全量读入——关键在分块读取 + 增量更新。
正确做法:用 update() 分块喂数据
核心是打开文件为二进制模式,每次读固定大小(如 8192 字节),调用 md5.update() 累加哈希状态。这样内存占用恒定,与文件大小无关。
- 推荐块大小:
8192(8KB)或65536(64KB),太小增加系统调用开销,太大无实质收益 - 必须用
rb模式打开,文本模式会破坏二进制数据 - 别忘了最后调用
md5.hexdigest()获取 32 位十六进制字符串
import hashlib
def calc_md5(filepath):
md5 = hashlib.md5()
with open(filepath, "rb") as f:
for chunk in iter(lambda: f.read(8192), b""):
md5.update(chunk)
return md5.hexdigest()
遇到 UnicodeDecodeError 就说明你用了文本模式
这个错误不是编码问题,而是你误用了 "r" 模式打开二进制文件。Python 试图用默认编码(如 UTF-8)解码非文本字节,立刻报错。解决方法只有且必须:改回 "rb"。
- 常见诱因:复制网上代码时漏掉
b,或 IDE 自动补全误导 -
open(..., "r").read()对大文件还可能隐式触发解码尝试,哪怕没显式 .decode() - Windows 上尤其容易中招,因为某些编辑器保存的文件带 BOM,更易触发解码失败
需要更高性能?试试 mmap(但慎用)
对超大文件(>10GB)且磁盘 I/O 是瓶颈时,mmap 可减少数据拷贝,但代价是复杂性和平台差异:
- Linux/macOS 支持良好;Windows 上需注意
access=mmap.ACCESS_READ和文件关闭顺序 - 仍要配合
md5.update(),只是数据源从f.read()换成内存映射切片 - 实际提升有限——现代 SSD 下,纯
read()分块已足够快;mmap 主要优势在随机访问场景,而非顺序哈希
真正容易被忽略的是:校验前先确认文件没被其他进程写入。边写边算 MD5 会导致结果不可靠,且 Python 不会主动报错。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











