Dot-Net

我應該如何輪詢大量文件以進行更改?

  • October 17, 2011

我想輪詢文件系統是否有任何更改、添加或刪除的文件或子目錄。應快速檢測所有變化,但不對機器施加壓力。作業系統是 Windows >= Vista,觀察到的部分是本地目錄。

通常,我會求助於 FileSystemWatcher,但這會導致其他試圖觀看同一地點的程序出現問題(主要是 Windows 資源管理器)。另外,我聽說即使對於本地文件夾和大緩衝區,FSW 也不是很可靠。

我遇到的主要問題是文件和目錄的數量可能非常大(猜 7 位數)。簡單地每秒檢查所有文件確實會明顯影響我的機器。

我的下一個想法是每秒檢查整個樹的不同部分以減少整體影響,並可能添加一種啟發式方法,例如檢查快速連續頻繁更改的文件。

我想知道這種問題是否有模式,或者是否有人有這種情況的經驗。

我們使用 C# 實現了類似的功能。FileSystemWatcher 對於大型目錄樹效率低下。

我們的替代方案是使用FSNodes我們創建的結構,使用以下 Windows API 呼叫:

   [StructLayout(LayoutKind.Sequential)]
       private struct FILETIME
   {
       public uint dwLowDateTime;
       public uint dwHighDateTime;
   };

   [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
       private struct WIN32_FIND_DATA
   {
       public FileAttributes dwFileAttributes;
       public FILETIME ftCreationTime;
       public FILETIME ftLastAccessTime;
       public FILETIME ftLastWriteTime;
       public uint nFileSizeHigh;
       public uint nFileSizeLow;
       public int dwReserved0;
       public int dwReserved1;
       [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_PATH)]
       public string cFileName;
       [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_ALTERNATE)]
       public string cAlternate;
   }

   [DllImport("kernel32.dll", SetLastError = true)]
   static extern bool FindClose(IntPtr hFindFile);

   [DllImport("kernel32", CharSet=CharSet.Unicode)]
   private static extern IntPtr FindFirstFile(
       string lpFileName, out WIN32_FIND_DATA lpFindFileData);

   [DllImport("kernel32", CharSet=CharSet.Unicode)]
   private static extern bool FindNextFile(
       IntPtr hFindFile, out WIN32_FIND_DATA lpFindFileData);

我們所做的是靜態處理。我們將元數據樹保存在磁碟上,並將儲存的目錄樹與載入的目錄樹進行比較,搜尋已修改(基於其時間戳(更快)或文件雜湊)。此外,我們可以管理刪除、添加和移動,甚至移動修改的文件(也基於文件雜湊)。

這個實現與每個 POLL_TIME 執行它的守護程序混合在一起,對我們來說是有效的。希望能幫助到你。

引用自:https://stackoverflow.com/questions/7203989