关键在于稳准快:确保文件落盘完成、分块流式读取避免OOM、统一哈希格式为小写十六进制字符串。Java中推荐try-with-resources保障落盘,MessageDigest配合FileInputStream循环更新,或直接使用Apache Commons Codec的DigestUtils一行调用。

快速校验大文件的 MD5 或 SHA-256,关键不在“快”,而在“稳准快”——避免内存溢出、确保落盘完成、统一比对格式。用对方式,几 GB 文件几十秒内就能得出可靠结果。
确保文件已真正写入磁盘再计算
很多校验失败不是算法问题,而是文件还没落盘就急着算哈希。Java 的 OutputStream 默认缓冲,write() 返回不等于数据已写入磁盘。
- 写完后显式调用 flush() + getChannel().force(true),强制同步到磁盘
- 更推荐用 try-with-resources 自动关闭流,close() 会隐式触发 flush 和 fsync
- 别依赖“写完就立刻算”,尤其在 NFS、USB 设备或低配 SSD 上,延迟更明显
用流式分块读取,避开 OOM
把几 GB 文件一次性 load 到内存,极易触发 OutOfMemoryError。必须边读边哈希,不缓存全文。
- 用 FileInputStream 配合固定 buffer(如 8192 字节),循环 read()
- 每次读到有效字节后,调用 md.update(buffer, 0, bytesRead)
- 全程不 new byte[文件大小],也不调用 Files.readAllBytes() 或 Files.readString()
选对工具:原生 MessageDigest 还是 Commons Codec?
两者都可行,但适用场景不同:
立即学习“Java免费学习笔记(深入)”;
- 原生 MessageDigest:无额外依赖,适合轻量项目;注意每次都要 MessageDigest.getInstance("SHA-256")(不能复用实例)
- Apache Commons Codec:一行代码搞定,DigestUtils.sha256Hex(file) 内部已做流式处理和异常封装,实测 10GB 文件约 25–35 秒(SSD 环境)
- 若项目已引入 commons-codec,优先用它;若追求零依赖,手写流式逻辑更可控
生成与比对时统一格式
哈希值看似简单,格式不一致就会导致“明明一样却判为不同”。
- 输出一律转为 小写 32 位(MD5)或 64 位(SHA-256)十六进制字符串
- 比对前对预期值 trim() + 去除 md5=、sha256: 等前缀
- JDK 17+ 推荐用 HexFormat.of().formatHex(digest);老版本可用 String.format("%02x", b) 循环拼接


















