0

我编写了一个 Python 脚本来比较两个目录中的文件,使用filecmp.cmp. 它可以工作,但刚才我尝试为一组大文件运行它。这是非常缓慢的。

文档说当shallow参数为真时(默认情况下),filecmp.cmp应该只比较os.stat结果。

对于另一个大型文件集合,该脚本运行得更快jpg。我想知道为什么文件大小比文件数量的影响更大,就好像它只检查一样os.stat

4

1 回答 1

3

我认为该shallow参数的文档具有误导性*。传递shallow = True并不一定会阻止filecmp.cmp函数比较文件的内容。如果您的文件大小相同但mtimes 不同,仍然会检查它们的内容。

你可以在你的 Python 安装中看到 的实现,或者你可以在Python 源代码库cmp中查看(目前的)源代码。

以下是相关位cmp

def cmp(f1, f2, shallow=True):
    # long docstring removed

    s1 = _sig(os.stat(f1))
    s2 = _sig(os.stat(f2))
    if s1[0] != stat.S_IFREG or s2[0] != stat.S_IFREG:
        return False
    if shallow and s1 == s2:
        return True
    if s1[1] != s2[1]:
        return False

    # rest of function, which calls a helper to do the actual file contents comparisons

辅助函数返回从文件的数据结构_sig中提取的值的元组。stat元组值是文件类型、文件大小及其mtime(通常是上次修改文件内容的时间)。

我在代码摘录中包含的测试试图根据这些元数据快速确定两个文件是否相同。如果任一文件不是“常规”文件(因为它是目录或特殊系统文件),则它们被视为不相等。此外,如果它们的大小不同,则它们不可能相等。

shallow参数的作用是允许快速阳性测试。如果shallow为真并且文件具有相同的大小并且mtime,filecmp.cmp将假定文件是相等的。

我怀疑您的程序中发生的事情是您的当前目录中有许多大小完全相同的文件(可能是因为内容非常相似,或者因为文件大小由数据格式固定)。您以前的数据集没有那么多相同大小的文件,因此您的代码能够快速排除它们。

* 我认为filecmp.cmp's 的文档字符串具有误导性,以至于它表明存在错误(因为它没有正确描述行为,或者因为实际实现不正确,应该修复以匹配文档)。看起来我并不孤单。这是一个关于这个问题的错误报告,尽管它已经好几年没有更新了。我会用这个问题的链接来解决这个错误,也许有人会努力修复它!

于 2014-04-21T08:17:13.813 回答