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

本文关键字:文件 查找 | 更新日期: 2023-09-27 18:21:22

我正在文件服务器上查找给定唯一文件的所有重复项。以下是我所做的:

  1. 获取唯一文件的哈希代码
  2. 将唯一文件的哈希代码与文件服务器上每个文件的哈希码进行比较。如果相等,则添加到重复项列表中

这可以完成任务,但需要很长时间(我在文件服务器上有20万个文件),所以我不得不考虑其他事情,这就是我所做的:

  1. 获取唯一文件的哈希代码
  2. 获取唯一文件的大小(以字节为单位)
  3. 获取具有相同文件大小的所有文件的列表(这非常快,因为我不需要读取文件)
  4. 将唯一文件的哈希代码与入围文件中的每个文件进行比较

这将完成任务所需的时间从几个小时减少到了10分钟,但这仍然不好,尤其是在试图为一堆文件查找重复文件时。每次文件搜索需要10分钟,意味着100个文件将需要16个小时!

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

谢谢你,

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

通过哈希码搜索重复项无疑是最慢的方法;大量的磁盘i/o和cpu处理。

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

  1. 按文件大小分组的短列表
  2. 逐字节比较每组所有这些文件的前256个字节。这应该会消除很多文件
  3. 在步骤2上循环,但在每次迭代时将缓冲区大小增加一倍(最大值为16K左右)

在循环中打开/关闭所有这些文件句柄确实是一个轻微的开销,但不如完全读取所有文件那么大。

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

目前有两种比较文件的方法——获取文件大小(快速且准确)和哈希("缓慢"且足够准确)。问题是,当文件大小不可忽略时,计算文件的哈希可能需要一段时间。

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

  • 如果你的输入是文本文件,那么比较它们第一句话(或X个第一个字符)上的哈希可能非常好(假设不是所有的都是以"Hello World"或任何其他常见模板开头的字母)
  • 如果您的输入是图像文件,则比较它们的内部元数据(如所花费的时间/地理标记/其他一些不太常见的字段)也可以产生相对快速的比较,从而解决许多潜在的相等性
  • 如果你的输入文件只是文件共享网站上的随机文件,由于文件格式的标题,读取它们的前几个字节应该会将其中许多文件区分开来(甚至更好——如果你的用户没有将文件命名为"Hello.jpg"answers"Hello.jpeg",那么通过后缀区分文件也可以进行快速比较)

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

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