如何比较2卷和列出修改过的文件?

时间:2010-08-28 18:03:08

标签: c++ winapi backup ntfs volume

我有2个硬盘卷(一个是另一个的备份映像),我想比较卷并列出所有修改过的文件,以便用户可以选择他/她想要回滚的那些

目前我正在通过新卷进行递归,并将每个文件的时间戳与旧卷的文件进行比较(如果它们在旧卷中)。显然这是一个错误的方法。这是耗时而错误的!

有没有一种有效的方法呢?

编辑:
- 我正在使用FindFirstFile并喜欢递归音量,并收集每个文件的信息(不是很慢,只需几分钟)。
- 我正在使用卷影复制进行备份 - 备份卷是远程的,所以我不能连续监视实际音量。

5 个答案:

答案 0 :(得分:2)

部分原因取决于两卷的重复方式;如果它们是从文件系统的角度来看的“真实”副本(例如卷影副本或其他块级副本),你可以针对USN做一些棘手的小事,这是其他人建议你研究的一般技术。例如,您可能希望查看类似FSCTL_READ_FILE_USN_DATA的API。该API将允许您比较文件的两个不同副本(同样,假设它们是相同的文件,具有来自块级备份的相同文件引用号)。如果你想在很大程度上无国籍,这个和类似的API会在这里帮助你很多。我的算法看起来像这样:

foreach( file in backup_volume ) {
    file_still_exists = try_open_by_id( modified_volume )
    if (file_still_exists) {
        usn_result = compare_usn_values_of_files( file, file_in_modified_volume )
        if (usn_result == equal_to) {
           // file hasn't changed at all
        } else {
           // file has changed (somehow)
        }
    } else {
        // file was deleted (possibly deleted and recreated)
    }
}
// we still don't know about files new in modified_volume

所有这一切都说,我的经历让我相信这将比我的袖口解释提示更加复杂。不过,这可能是一个很好的起点。

如果卷不是彼此的块级副本,那么比较USN号和文件ID将非常困难,如果不是不可能的话。相反,您很可能会按文件名进行操作,如果不打开每个文件,这将很难做到(时间可以通过应用程序修改,大小和时间可能会在findfirst / next查询中过时,而您必须处理已删除然后重新创建的案例,重命名案例等。)。

因此,了解您对环境的控制程度非常重要。

答案 1 :(得分:1)

我没有等到更改发生后再扫描整个磁盘以查找已更改的(通常很少)文件,而是设置了一个程序来使用ReadDirectoryChangesW来监控更改因为他们发生了。这将使您可以构建一个文件列表,并且可以轻松打扰。

答案 2 :(得分:0)

假设您没有将新卷上的每个文件与快照中的每个文件进行比较,这是您可以执行此操作的唯一方法。如果不查看所有文件,您将如何找到未修改的文件?

答案 3 :(得分:0)

我不是Windows程序员。 但是,您不应该使用stat函数来检索文件的修改时间。 根据模式时间对文件进行排序。 模式时间大于上次备份时间的文件是您感兴趣的文件。

第一次你可以迭代备份音量来计算最大模态时间并从感兴趣的集合中创建时间。 我假设感兴趣的目录没有在备份卷中修改。

答案 4 :(得分:0)

在不知道你要在这里做什么的更多细节的情况下,很难说。但是,关于我想要实现的想法的一些提示:

  • 如果您只关心NTFS卷,我建议您查看USN / change journal API。它们自2000年以来一直存在。这样,在初始库存之后,您只能查看从那一点开始的变化。这是一个很好的起点,虽然这里有一篇非常古老的文章:http://www.microsoft.com/msj/0999/journal/journal.aspx
  • 此外,利用USN API,你可以省略哈希步骤,只是自己记录来自期刊的信息(当你查看所述API时,这将变得更加清晰)。
  • 第一次通过比较驱动器的内容,使用SHA-1或MD5等散列。
  • 将哈希值和其他此类信息存储在某种数据库中。例如,SQLite3。请注意,这可能会占用大量空间。快速查看我的带有40k +文件的音频文件夹将产生~750兆的MD5信息。