不能直接用hashlib.md5(file.read())读大文件,因为file.read()会一次性将整个文件加载进内存,导致memoryerror或系统变慢;正确做法是用'rb'模式打开文件,以固定块大小(如8192字节)循环read()并调用update()流式计算,最后用hexdigest()获取结果。

为什么不能直接用 hashlib.md5(file.read()) 读大文件?
因为 file.read() 会把整个文件一次性加载进内存,1GB 文件就吃掉 1GB 内存,容易触发 MemoryError 或拖慢系统。实际场景中,几 GB 的日志、镜像、视频文件很常见,必须流式分块读取。
正确做法:用 update() 分块喂数据
核心是打开文件后,每次只读固定大小(如 8192 字节),反复调用 hash_obj.update(chunk),最后调用 hexdigest() 获取结果。这样内存占用恒定,与文件大小无关。
推荐代码片段:
import hashlib
<p>def compute_hash(filepath, algorithm='md5', chunk_size=8192):
hash_obj = getattr(hashlib, algorithm)()
with open(filepath, 'rb') as f:
while chunk := f.read(chunk_size):
hash_obj.update(chunk)
return hash_obj.hexdigest()</p><h1>示例</h1><p>print(compute_hash('large_file.iso', 'sha256'))</p>
-
chunk_size设为 8192(8KB)是通用平衡值;设太小(如 1)会导致系统调用过多,性能下降;设太大(如 1MB)对内存压力虽仍可控,但没必要 -
algorithm支持'md5'、'sha1'、'sha256'、'sha512'等,传错名字会抛AttributeError - 必须用
'rb'模式打开,否则文本模式在 Windows 上可能因换行符处理出错,哈希值不一致
遇到 UnicodeDecodeError 怎么办?
这通常是因为误用了文本模式('r')打开二进制文件,或手动做了 .decode()。哈希计算只认字节序列,跟编码无关。只要确保 open(..., 'rb') + bytes 流,就不会触发该错误。
常见误操作:
- 写成
open(filepath).read()→ 缺少'rb',默认文本模式 - 写成
hash_obj.update(f.read().encode())→ 多余 encode,且文本读取本身已失败 - 用
pandas.read_csv()或json.load()先加载再哈希 → 完全偏离目标,破坏原始字节
想验证下载完整性?注意校验和文件本身的编码
很多项目提供 .md5 或 .sha256 校验文件,内容形如 abc123... filename.zip。注意空格分隔符位置和末尾换行 —— 有些用空格,有些用制表符;有些末尾带 \n,解析时需 strip()。
安全比对建议:
- 用
split(None, 1)拆分,避免空格/制表符差异影响 - 校验前先确认你算出的哈希值和官方提供的完全一致(包括大小写,
hexdigest()返回小写) - 不要用
==直接比字符串,可用hmac.compare_digest()防计时攻击(虽一般场景不必要,但严谨项目值得加)
真正容易被忽略的是:不同操作系统生成的校验文件可能含 BOM 或 CRLF,拿 Windows 下下载的 .sha256 在 Linux 里直接 cat 解析,可能多出不可见字符。动手前先 hexdump -C checksum.sha256 | head 看一眼开头字节最稳妥。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











