65.9K
CodeProject 正在变化。 阅读更多。
Home

重复文件查找器

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.89/5 (13投票s)

2008年8月2日

CPOL

4分钟阅读

viewsIcon

60083

downloadIcon

3185

一个在你的系统中查找重复文件的工具。

引言

我编写这个工具来查找我系统中的重复文件,并且想与大家分享。 因为这篇文章的主要目的是展示这个工具,所以需要写的东西相对较少。 但是,我将尝试描述该工具实现的基本机制。

如何使用

实际上,使用该工具非常容易。 您可以在此处看到它的界面。

duplicatefinder_src

除了具有“开始”按钮外,该工具还提供“停止”和“暂停”按钮,因为在大量文件中查找重复项可能需要很长时间。 扫描期间找到的重复文件会立即插入到树形控件 (CTreeCtrl) 中,正如你所看到的。 这是一个两级层次结构,在第二级保存重复的文件名,在第一级保存常规信息。 你还可以以文本形式记录生成的层次结构(当搜索过程结束时,“Log...”按钮将被启用)。 通常,该工具运行速度非常快; 例如,扫描大约 70 GB 大小的目录需要大约 40 分钟。 但是,对于单次扫描来说,这个大小是不是太大了?

工作原理

在这里,我将描述实现的底层策略。 用户界面通过 MFC 实现(使用了 VC7.1,抱歉我没有 VC9)。 扫描过程是在一个单独的工作线程中完成的,以便用户可以在任何时候停止/暂停执行。 该线程在用户开始新的扫描时启动,并在用户停止扫描或没有更多文件要扫描时结束。 而且,正如你猜测的那样,主要引擎集中在工作线程本身中。 它可以将它执行的步骤归纳为以下大纲:

  • 收集有关目录大小的必要信息
  • 保留足够的虚拟内存来保存已扫描的文件名
  • 开始扫描目录
  • 释放资源

以下是上面几点的更详细的描述:

  • 收集关于目录大小的必要信息:这个过程是通过 CFileFind MFC 实用工具类完成的,通过它来遍历每个文件以计算目录中的总文件数。 我一直在努力寻找 Win32 等效项,但无济于事。 而且,如果您碰巧知道一个返回目录中文件数量的 Win32 API,请告诉我。
  • 保留足够的虚拟内存来保存已扫描的文件名:该实现使用 VirtualAllocVirtualFree 来分配/释放虚拟内存块。 由于要扫描的目录可能非常大,因此最好将扫描的文件名存储在虚拟内存中,而不是直接存储在 RAM 中。 因此,需要此虚拟内存来存储已经扫描过的文件名。 正在扫描的下一个文件应该针对已经扫描的文件表中的重复项进行测试。 为了优化这个过程(即,不遍历表中的所有条目),它保持表排序(按文件内容,而不是它们的名称),并使用二分搜索来查找重复项(如果没有找到,它会找到将文件名插入表中的位置)。
  • 开始扫描目录:扫描过程选择下一个文件,并测试它是否是重复项。 为了选择下一个文件,再次使用 CFileFind MFC 类。 那么,我们如何比较两个文件呢? 该工具执行两个文件的逐位比较。 也就是说,它打开它们,并按字典顺序比较它们的内容(就像两个字节字符串一样)。 为了优化这个过程,这些文件被作为内存映射文件打开,并且它们的内容通过 C 运行时例程 memcmp 进行比较。 为了自动化这个过程,我编写了一个类 CMMFile 来处理所有这些过程。 它还确保如果一个文件不能被映射(由于内存不足),它将被逐部分地比较(这些部分会足够小以能够成功映射)。
  • 释放资源:在扫描过程结束后,需要释放资源,例如,分配的虚拟内存。

致谢

该工具使用了两篇文章。 感谢 Dana Holt 的 他的文章,关于浏览文件夹。 还有, 第二篇是我写的,它提供了一个简单的类,封装了 VirtualAlloc/VirtualFree Win32 API 函数。 当然,非常感谢本文的读者和用户!

© . All rights reserved.