如何查看目录的子文件是否已更改

Windows中,是否有一个简单的方法来判断一个文件夹是否有一个已经改变的子文件?

我validation了,文件夹上的最后修改date在子文件更改时不会更新。

有没有我可以设置,将修改此行为的registry项?

如果重要,我正在使用NTFS卷。

我最终想从C ++程序中获得这个能力。

以recursion方式扫描整个目录对我来说不起作用,因为该文件夹太大了。

更新:我真的需要一种方法来做到这一点,而没有一个进程在更改发生时运行。 所以安装一个文件系统监视器对我来说并不是最理想的。

Update2:归档位也将无法正常工作,因为它具有与上次修改date相同的问题。 该文件的归档位将被设置,但文件夹不会。

这篇文章应该帮助。 基本上,您创建一个或多个通知对象,如:

 HANDLE dwChangeHandles [2]; 
 dwChangeHandles [0] = FindFirstChangeNotification( 
       lpDir,//要观看的目录 
      假,//不要看子树 
       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);  //观察目录名称更改 

   如果(dwChangeHandles [1] == INVALID_HANDLE_VALUE) 
    {
      printf(“\ n错误:FindFirstChangeNotification函数失败。\ n”);
     了ExitProcess(GetLastError函数()); 
    }

然后你等待通知:

  while(TRUE) 
    { 
    //等待通知。 
       printf(“\ n等待通知... \ n”);

       DWORD dwWaitStatus = WaitForMultipleObjects(2,dwChangeHandles, 
          FALSE,INFINITE); 

      开关(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在等待调用中使用不发生变化。
          //在单线程的环境中,你可能不需要一个
          // INFINITE等待。

             printf(“\ n没有更改超时期限\ n”);
            打破;

         默认: 
             printf(“\ n错误:未处理的dwWaitStatus。\ n”);
            了ExitProcess(GetLastError函数());
            打破;
       }
    }
 }

这可能是矫枉过正,但是来自MS的IFS套件或OSR的FDDK可能是另一种选择。 创建自己的文件系统过滤器驱动程序,并对文件系统的所有更改进行简单的监视。

ReadDirectoryChangesW

这个CodeProject文章中的一些优秀的示例代码

如果在发生更改时无法运行进程,则除了扫描文件系统并检查修改日期/时间之外,没有什么可以做的了。 这需要您存储每个文件的最后日期/时间,然后进行比较。

您可以使用存档位来加快速度(尽管可能会弄乱备份软件,请谨慎操作)。

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

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

存档位不受简单读取文件的影响。 复制文件时,原始文件的存档位不受影响,但复制的存档位将在复制时设置。

所以这个过程将是:

  1. 清除所有文件上的存档位
  2. 让文件系统随着时间而改变
  3. 扫描所有的文件 – 任何与存档位设置已经改变

这将消除您的程序保持状态的需要,而且由于您只是查看目录条目(存储位),并将它们聚集在一起,所以它应该非常快速。

如果你可以在更改过程中运行一个进程,那么你需要查看FileSystemWatcher类。 这里有一个如何使用它的例子 。

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

也许你可以让一个进程在机器上运行,观察变化并创建一个文件供你稍后阅读。

-亚当

也许你可以像这里解释的那样使用带有DeviceIoControl的NTFS 5 Change Journal

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

从双重职位提到的人:WMI事件接收器

尽管如此,仍然在寻找更好的答案。

不容易 – 如果您有一个正在运行的应用程序,您可以使用Win32文件更改通知apis(FindFirstChangeNotification)的建议与其他答案。 警告:大约2000趋势微型实时病毒扫描程序会将这些更改分组在一起,因此在请求文件系统更改列表时有必要使用非常大的缓冲区。

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