【问题标题】:How to see if a subfile of a directory has changed如何查看目录的子文件是否已更改
【发布时间】:2010-09-08 13:44:46
【问题描述】:

在 Windows 中,是否有一种简单的方法可以判断文件夹是否有已更改的子文件?

我已验证,当子文件更改时,文件夹的最后修改日期不会更新。

我可以设置一个注册表项来修改此行为吗?

如果重要的话,我使用的是 NTFS 卷。

我最终希望从 C++ 程序中获得这种能力。

递归扫描整个目录对我不起作用,因为该文件夹太大了。

更新:我真的需要一种方法来做到这一点,而无需在更改发生时运行进程。所以安装文件系统观察器对我来说不是最佳选择。

Update2:存档位也将不起作用,因为它与上次修改日期存在相同的问题。将设置文件的存档位,但不会设置文件夹。

【问题讨论】:

  • 虽然不像在文件夹本身上翻转存档位那样容易,但如果 Windows 最终不支持将存档标志自动“滚动”到文件夹级别,请阅读直到找到至少一个考虑到您的上述问题,带有存档标志的文件(或没有文件)可能是您唯一的选择
  • 你能做一个“Update3”解释为什么 NTFS 日志不适合你吗?
  • 因为我也想通过网络访问
  • Serge 的回答 (stackoverflow.com/questions/56682/…) 也应该涵盖网络案例。

标签: c++ windows filesystems ntfs


【解决方案1】:

这个article 应该会有所帮助。基本上,您创建一个或多个通知对象,例如:

处理 dwChangeHandles[2]; dwChangeHandles[0] = FindFirstChangeNotification( lpDir, // 观察目录 FALSE, // 不看子树 FILE_NOTIFY_CHANGE_FILE_NAME); // 观察文件名变化 如果(dwChangeHandles[0] == INVALID_HANDLE_VALUE) { printf("\n 错误:FindFirstChangeNotification 函数失败。\n"); ExitProcess(GetLastError()); } // 观察子树目录的创建和删除。 dwChangeHandles[1] = FindFirstChangeNotification( lpDrive, // 观看的目录 TRUE, // 观察子树 FILE_NOTIFY_CHANGE_DIR_NAME); // 观察目录名称变化 if (dwChangeHandles[1] == INVALID_HANDLE_VALUE) { printf("\n 错误:FindFirstChangeNotification 函数失败。\n"); ExitProcess(GetLastError()); }

然后你等待通知:

而(真) { // 等待通知。 printf("\n等待通知...\n"); DWORD dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles, 错误,无限); 开关(dwWaitStatus) { 案例 WAIT_OBJECT_0: // 在目录中创建、重命名或删除文件。 // 重启通知。 if ( FindNextChangeNotification(dwChangeHandles[0]) == FALSE ) { printf("\n 错误:FindNextChangeNotification 函数失败。\n"); ExitProcess(GetLastError()); } 休息; 案例 WAIT_OBJECT_0 + 1: // 重启通知。 if (FindNextChangeNotification(dwChangeHandles[1]) == FALSE) { printf("\n 错误:FindNextChangeNotification 函数失败。\n"); ExitProcess(GetLastError()); } 休息; 案例WAIT_TIMEOUT: // 发生超时。如果其他一些价值会发生这种情况 // 而不是在等待调用中使用 INFINITE 并且不会发生任何更改。 // 在单线程环境中,您可能不需要 // 无限等待。 printf("\n超时时间没有变化。\n"); 休息; 默认: printf("\n 错误:未处理的 dwWaitStatus.\n"); ExitProcess(GetLastError()); 休息; } } }

【讨论】:

  • 然而,这不是布赖恩所要求的;对于某些文件(在文件夹中)只是被修改(而不是重命名,并且没有创建或删除子目录/文件)的情况,这个答案没有提供解决方案。
  • 看你理解的修改。如果你打算维护一个文件夹的镜像,那么如果有修改,就一定要重命名。
【解决方案2】:

这可能有点矫枉过正,但来自 MS 的 IFS kit 或来自 OSR 的 FDDK 可能是一个替代方案。创建您自己的文件系统过滤器驱动程序,对文件系统的所有更改进行简单监控。

【讨论】:

    【解决方案3】:

    ReadDirectoryChangesW

    this CodeProject article中的一些优秀示例代码

    【讨论】:

    • Serge,用一个适用于该问题的示例扩展您的建议。
    • ΤZΩΤZΙΟΥ,我添加了一个包含示例代码的非常好的 CP 文章的链接
    【解决方案4】:

    如果在更改发生时您无法运行进程,那么除了扫描文件系统并检查修改日期/时间之外,您无能为力。但是,这需要您存储每个文件的最后日期/时间并进行比较。

    您可以使用archive bit 加快此过程(尽管它可能会弄乱您的备份软件,因此请谨慎操作)。

    存档位是文件属性 存在于许多计算机文件系统中, 尤其是 FAT、FAT32 和 NTFS。这 存档位的目的是跟踪 对文件的增量更改 备份的目的,也称为 归档。

    由于归档位是二进制位,它 是 1 或 0,或者在这种情况下更多 经常称为 set (1) 和 clear (0)。操作系统设置 任何时候文件的归档位 创建、移动、重命名或以其他方式 以任何方式修改。存档位 因此代表两个之一 状态:“已更改”和“未更改” 自上次备份以来。

    存档位不受 只是读取一个文件。当一个文件是 复制,原始文件的存档 位不受影响,但副本的 存档位将在当时设置 副本已制作。

    所以流程是:

    1. 清除所有文件的存档位
    2. 让文件系统随时间变化
    3. 扫描所有文件 - 任何设置了存档位的文件都已更改

    这将消除您的程序保持状态的需要,并且由于您只检查目录条目(存储位的位置)并且它们是集群的,因此它应该非常非常快。

    但是,如果您可以在更改期间运行进程,那么您将需要查看 FileSystemWatcher 类。这是一个example,您可能会如何使用它。

    它也存在于.NET中(对于此类问题的未来搜索者)

    也许您可以让机器上运行的进程监视更改并创建文件供您稍后阅读。

    -亚当

    【讨论】:

    • 根据您的应用程序的性质,更改您不“拥有”的文件的存档位不一定是一个好主意...
    【解决方案5】:

    也许您可以按照here 的说明将 NTFS 5 更改日志与 DeviceIoControl 一起使用

    【讨论】:

      【解决方案6】:

      如果您不反对使用 .NET,FileSystemWatcher 类会很容易地为您处理这个问题。

      【讨论】:

        【解决方案7】:

        来自某人提到的双重帖子:WMI Event Sink

        但仍在寻找更好的答案。

        【讨论】:

          【解决方案8】:

          没有什么容易的 - 如果您有一个正在运行的应用程序,您可以按照其他答案的建议使用 Win32 文件更改通知 API (FindFirstChangeNotification)。警告:大约 2000 年的 Trend Micro 实时病毒扫描程序会将更改组合在一起,因此在请求文件系统更改列表时需要使用非常大的缓冲区。

          如果您没有正在运行的应用程序,您可以打开 ntfs 日志并扫描日志以查找更改http://msdn.microsoft.com/en-us/library/aa363798(VS.85).aspx,但是当更改数大于文件数时,这可能比扫描整个目录要慢.

          【讨论】:

            猜你喜欢
            • 2012-03-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-06-07
            • 1970-01-01
            • 2010-12-18
            • 2023-03-21
            相关资源
            最近更新 更多