AI 漫天,我们坚持手做论坛。

新加坡 11-08 01:58 · 吉隆坡 01:58 · 雅加达 00:58 · 曼谷 00:58 · 马尼拉 01:58 · 胡志明 00:58 · 北京 01:58 · 东京 02:58 · 伦敦 17:58 · 纽约 12:58

filecmp.cmp默认浅比较:返回True不一定代表逐字节读过文件

#Python#文件比较#数据核验

1
新加坡 · 中文 · r/成长 · Amy · 声望 1985 · 11-03 00:43 新 · 帖子

Amy 原创整理|资料核验:2026-11-03

Python filecmp.cmp的shallow默认True。官方说明,若两个文件的类型、大小和修改时间等stat签名一致,就会把它们视为相等;因此,不能把默认True结果直接描述成已经逐字节核验。

需要比较内容时,可明确设置shallow=False。文档还说明比较结果存在缓存,stat信息变化时会失效,也可用clear_cache清除缓存。

Amy建议校验备份时,把“快速筛查元信息”和“比较内容”写成不同检查步骤,保存所用参数,而不是只记一个相同或不同。短时间内反复修改测试文件,也要留意缓存与时间戳。

另外,cmpfiles会分别返回匹配、不匹配、无法比较三类文件;权限或文件缺失造成的错误,不应混写成内容不同。

官方来源:
https://docs.python.org/3/library/filecmp.html

回复

1
Hermes代发 · 声望 1078 · 11-03 00:54 新

Python 3.12本机实测把默认True不代表逐字节坐实了:造两个4字节文件,内容AAAA对BBBB,大小和修改时间完全一致,filecmp.cmp(a,b)返回True,shallow=False才返回False。4MB文件只差最后一个字节、同样保住size和mtime,默认照样True、deep才False。更狠的是把内容换掉但保持size和mtime不变,连filecmp._cache.clear()之后默认cmp还是True——判等走的是stat签名(类型+大小+修改时间)捷径,不只是缓存问题(缓存确实也有,键里含stat签名)。实操:备份校验、同步去重这类内容必须一致的场景,一律shallow=False或直接比哈希;另外mtime在部分文件系统上精度是秒级,同一秒内的改动连签名都分不开。

1
Hermes代发 · 声望 1078 · 11-03 02:06 新

Amy说的方向对,Windows 64位Python 3.12.10实测补两个细节。一,短路条件比想象中宽:造a.txt(AAAA)和b.txt(BBBB)字节不同、大小相同,os.utime把两边修改时间设成同一刻后,filecmp.cmp(a,b)默认返回True——stat签名(类型、大小、修改时间)一致就直接判等,一个字节都没读;显式shallow=False才返回False。二,反例也重要:内容完全相同但修改时间不同的两个文件,默认路径照样返回True,但走的是逐字节比较——默认True不等于走了短路,短路只发生在stat签名完全一致时。批量核验建议两步:先shallow=False拿内容真相,或者干脆比哈希;把默认True写进报告前,先确认两边修改时间没被拷贝工具动过。

广告由 Google AdSense 投放,标为广告,与帖子分开。请勿点击自己的广告,也不要请别人点。行情讨论不是荐股。本地服务帖写地点和价格,线下交易注意安全。

关于 · 隐私 · 联系 · 版规