我正在编写一个程序来查找文件的重复项。
我有两个文件夹,我必须在其中找到重复项。在最坏的情况下,我必须将所有文件相互比较。我正在考虑生成每个文件的校验和,比较校验和,然后如果校验和相等,则执行逐字节检查以确保文件完全相同。
问题是什么校验和生成器将足够快以浪费时间而不是仅仅逐字节检查?
您可以通过获取文件的完整列表然后按长度排序来减少必须进行的比较次数以及 I/O 的数量。如果两个文件的长度不同,它们就不能相同。因此,除了获取目录信息之外,您无需执行任何 I/O 即可消除大量文件,无论如何您都必须获取这些信息。
如果只有两个长度相同的文件 X,那么您不必为这些文件计算校验和。直接比较就行了。
如果有三个或更多长度相同的文件,那么最好计算所有三个文件的校验和,比较校验和,然后在校验和匹配时进行逐字节比较。
首先,正如 Jim Mischel 所说,首先按长度对文件进行分组。
n
如果要比较的文件很大,通过获取文件的第一个字节来计算您的代表(这就是校验和)可能会更快。读取整个大文件以计算校验和以将其与前n
字节不同的另一个文件进行比较是低效的。理论上,第一个n
字节确定文件的唯一性与n
字节校验和一样。(如果某个长度的所有可能文件的可能性相同,就是这种情况)
当然,如果要比较的文件很小,则可以将整个文件作为其子集来读取。
任何校验和算法都可以。例如,您可以使用 MD5。您几乎不会浪费任何时间,因为 I/O 比计算校验和所花费的 CPU 时间要慢得多。您也可以使用CRC32。
你说:“我有两个文件夹,我必须在其中找到重复项。” 我想在这里澄清一点。如果目标是查找重复文件,那么文件位于一个、两个或 x 个文件夹中都没有关系。假设您有 n 个文件,您需要按 n log n 的顺序进行比较来查找重复项。一次读取 n 个文件,计算它们的校验和,然后在 n log n 次中对校验和进行排序以查找重复项确实很有用。但是请注意,您可以通过首先比较文件大小来避免这种情况,并且仅在比较 3 个或更多相同大小的文件时才使用校验和。这将大大加快您搜索重复项的速度。