如何知道文件是否已更改?

时间:2014-08-07 18:17:52

标签: c++ windows winapi filesystems

我正在编写一个自定义C ++程序,该程序仅在文件自上次复制后在源中更改时才复制文件。所以我需要知道我的特定文件夹中的文件是否已更改。

我原本考虑在这些文件上计算SHA-1哈希值,但这可能意味着我必须在整个文件夹上执行此操作。另外,如果这些文件的大小是100GB,该怎么办?这意味着我必须在100GB的数据上计算SHA-1,这可能需要一些时间。

所以我很好奇是否有更好的方法可以做到这一点?

3 个答案:

答案 0 :(得分:1)

你至少有几种可能性。

一种方法是使用NTFS change journals来跟踪已修改的文件。

每个文件还有一个"存档"与之相关的旗帜。这通常由备份程序使用。无论何时写入文件,都会设置标志。复制/备份时,清除标记。如果要查看要复制/备份的文件,只需检查标志是设置还是清除。明显的问题:与其他备份程序冲突。

还有ReadDirectoryChangesW 1 。但是,这只能检测在使用它的代码运行时发生的更改。因此,要使用它来跟踪更改,您需要执行一些操作,例如设置始终在后台运行的服务以跟踪更改。根据文件及其修改方式,即使这样也可能会错过启动期间(服务开始执行之前)发生的更改。

我已经按照它们看起来如何适合您的需求的大致降序列出了这些 - 即,更改期刊几乎肯定是最合适的,存档标志第二和ReadDirectoryChangesW(相当于大幅度)最适合您的明显需求。


1.还有一个较旧的FindFirstChangeNotification / FindNextChangeNotification,但它们的功能较少,并且与ReadDirectoryChangesW具有相同的缺点。曾经有一段时间它们对于需要与Windows 95/98 / SE兼容的代码很有用(因为这些代码并不包括ReadDirectoryChangesW)但是它已经有好几年了。使用它们。 功能

答案 1 :(得分:1)

在对其他答案的评论中,您已声明不能使用文件监控API(例如FindFirstChangeNotification),因为您的代码可能在更改发生时未运行。

我建议采用多管齐下的方法。

  1. 如果您的应用程序正在运行,请使用文件监视API来检测新的更改。
  2. 启动时或出现新磁盘时,请检查文件大小是否与以前相同。如果不是,那么你知道你有变化。
  3. 如果文件大小相同,您可以使用文件的归档标志来确定它是否已更改。但是,存档标志很容易被用户更改,因此您可能不应该依赖它。
  4. 使用文件的上次更改时间戳。这可以由用户修改,但这样做更难。
  5. 使用哈希来确定文件是否已更改。您选择的哈希值取决于检测更改的重要性。如果它不重要,像CRC32或MD5就足够了。如果需要安全,请考虑SHA-256。考虑将大文件分成块。这样,在获得“此更改”结果之前,您不必对整个文件进行哈希处理。
  6. 这种分层方法可让您随时跳过昂贵的哈希值。

答案 2 :(得分:0)

如果你想在"实时"中使用,那么Windows有一个本机API。 FindFirstChangeNotifcation()