C#,最快(最好?)识别目录数组中的重复文件的方法

我想递归几个目录,并在n个目录之间找到重复的文件。

我在这方面的下意识是有一个全局哈希表或一些其他数据结构来保存我找到的每个文件; 然后检查每个后续文件以确定它是否在“主”文件列表中。 显然,我不认为这会非常有效,而且“必须有更好的方法!” 我的大脑里一直响个不停。

任何关于更好地处理这种情况的建议都将受到赞赏。

您可以通过首先比较文件大小来避免散列。 如果您从未找到具有相同大小的文件,则无需对其进行哈希处理。 只有在找到具有相同大小的另一个文件时才对文件进行哈希处理,然后对它们进行哈希处理。

这应该比盲目地散列每个文件快得多,尽管实现这种双层检查会更复杂。

我建议保留多个内存中的文件索引。

创建一个按文件长度索引所有文件的文件:

Dictionary> IndexBySize; 

当您处理新文件Fu ,快速查找以查找大小相同的所有其他文件。

创建另一个通过修改时间戳索引所有文件:

 Dictionary> IndexByModification; 

给定文件Fu ,您可以找到同时修改的所有文件。

对每个signficiant文件特征重复此操作。 然后,您可以使用Intersect()扩展方法有效地比较多个条件。

例如:

 var matchingFiles = IndexBySize[fu.Size].Intersect(IndexByModification[fu.Modified]); 

这将允许您在需要之前避免逐字节扫描。 然后,对于已经散列的文件,创建另一个索引:

 Dictionary> IndexByHash; 

您可能希望同时计算多个哈希值以减少冲突。

你的方法对我来说听起来很合理。 除非您有充分的理由认为它不足以满足您的性能要求,否则我只需按照这种方式实现它,并在必要时稍后对其进行优化。 请记住,“过早优化是邪恶的根源”。

正如John Kugelman所说,最好的做法是首先比较两个大小相同的文件,如果它们的大小不同,很明显它们不是重复的。

如果您找到两个大小相同的文件,为了获得更好的性能,您可以比较两个文件的前500 KB,如果前500 KB相同,则可以比较其余的字节。 这样你就不必读取(例如)500 MB文件的所有字节来获得其哈希值,这样可以节省时间并提高性能

对于你期望有很多重复项的字节比较,那么你可能最好使用你已经看过的方法。

如果您真的关心效率并且知道重复项将始终具有相同的文件名,那么您可以从单独比较文件名开始,并在找到重复名称时仅查找哈希字节。 这样,您可以节省在树中没有重复的散列文件的时间。