查找文件重复 - 最好是C#

时间:2014-09-10 06:05:31

标签: c# hashcode

我试图在文件服务器上找到给定唯一文件的所有重复项。这就是我所做的:

  1. 获取唯一文件的哈希码。
  2. 将唯一文件的哈希码与文件服务器上每个文件的哈希码进行比较。如果相等,则添加到重复列表中。
  3. 这可以完成工作但需要永远(我在文件服务器上有200k文件)所以我不得不考虑别的事情,这就是我所做的:

    1. 获取唯一文件的哈希码。
    2. 以字节为单位获取唯一文件的大小。
    3. 获取具有相同文件大小的所有文件的列表(这非常快,因为我不需要读取文件)
    4. 将唯一文件的哈希码与列入候选文件的每个文件进行比较。
    5. 这将执行任务所需的时间从几小时减少到10分钟,但这仍然不太好,尤其是在尝试查找一堆文件的重复项时。每次文件搜索需要10分钟,这意味着100个文件需要16个小时!

      是否有比哈希码更好的唯一文件标识符?获取哈希码是这个过程中耗时的事情。

      谢谢,

2 个答案:

答案 0 :(得分:4)

通过哈希码搜索重复项绝对是最慢的方式;很多磁盘i / o和cpu处理。

我在这个领域有一些经验,我们发现紧急方法是尽快消除文件:

  1. 按文件大小分组的短名单
  2. 逐个字节地比较每组所有这些文件的前256个字节。这应该消除很多文件。
  3. 在第2步循环,但每次迭代时缓冲区大小加倍(最大16K左右)
  4. 在循环中打开/关闭所有这些文件句柄确实是一个轻微的开销,但不如完全读取所有文件。

答案 1 :(得分:2)

好吧,既然这个问题涉及通过常数因素而不是数量级来优化运行时间,那么我们必须更加具体地了解您实际处理的文件类型。

您目前有两种比较文件的方法 - 获取其大小(快速且不准确)并获取其哈希(“慢”且足够准确)。问题是,当文件大小不可忽略时,计算文件的散列可能需要一段时间。

因此,根据您实际拥有的输入类型,您可能会在这两者之间进行更多的比较操作(比文件大小慢,但更准确)。例如:

  • 如果您的输入是文本文件,那么比较第一个句子(或X个第一个字符)的哈希值可能非常好(假设不是所有这些都是以“Hello World”开头的字母或任何其他常见模板)
  • 如果您的输入是图像文件,那么比较它们的内部元数据(例如时间/地理标记/某些其他字段与不常见的值)也可以导致相对快速的比较,从而解决许多潜在的等值
  • 如果您的输入文件只是文件共享网站上的随机文件,那么读取它们的前几个字节应该区分其中许多字节,因为文件格式标题(或者甚至更好 - 如果您的用户是不做命名文件“Hello.jpg”和“Hello.jpeg”,然后通过后缀区分文件也是一个快速的比较)

一般来说,如果你有很多类似大小的文件(这就是为什么你真的在后来的计算哈希上努力工作),那么这些文件很有可能有共同之处。鉴于您现在比我们更了解输入的类型,尝试提出不需要您阅读整个文件的比较标准,因此应该更快。

最后,当您拥有所有比较标准时 - 应用它们来创建输入的“桶”(输入列表与标准具有相同结果),从最快的标准开始,然后在每个桶中应用较慢的标准有多个输入。

相关问题