繁体   English   中英

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

[英]How to know if files have been changed?

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

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

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

您至少有两种可能。

一种是使用NTFS更改日志来跟踪已修改的文件。

每个文件还具有与之关联的“存档”标志。 这通常由备份程序使用。 每当您写入文件时,标志都会被设置。 复制/备份时,请清除该标志。 当您想查看要复制/备份的文件时,只需检查该标志是设置还是清除。 明显的问题:与其他备份程序冲突。

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

我已经按照它们似乎最适合您的需求的顺序从大到小的顺序列出了它们-即,更改日记几乎可以肯定是最合适的,存档标志位居第二,而ReadDirectoryChangesW (相当大的余量)最不适合您的需要需要。


1.还有一个较旧的FindFirstChangeNotification / FindNextChangeNotification ,但它们的通用性较差,并且与ReadDirectoryChangesW一样都有缺点。 一次它们对于需要与Windows 95/98 / SE兼容的代码很有用(因为它们不包含ReadDirectoryChangesW ),但是使用它们已经有好几年了。

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

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

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

这种分层方法使您可以随时跳过昂贵的哈希处理。

如果要“实时”执行此操作,Windows会为此提供本机API。 FindFirstChangeNotifcation()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM