首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

C# FileSystemWatcher 實現檔案目錄即時監控:完整封裝與持久化隊列

     編輯:更多程式設計知識

FileSystemWatcher 是 .NET 提供的檔案系統事件監聽元件,可監控建立、刪除、修改、重命名事件。本文提供生產級封裝:支援子目錄遞歸、事件去抖、記憶體隊列緩衝、可選磁碟持久化、自動重連機制。

核心事件與屬性設定

_watcher = new FileSystemWatcher(_path, _filter); // _filter 如 "*.txt" 或 "" 監控所有
_watcher.IncludeSubdirectories = true;            // 遞歸子目錄
_watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName
                       | NotifyFilters.LastWrite | NotifyFilters.Size
                       | NotifyFilters.Attributes;

_watcher.Created += OnProcess;
_watcher.Changed += OnProcess;
_watcher.Deleted += OnProcess;
_watcher.Renamed += OnFileRenamed;
_watcher.EnableRaisingEvents = true;              // 啟動監聽

事件處理去抖邏輯(關鍵)

private void OnProcess(object sender, FileSystemEventArgs e) {
  try {
    FileChangeType type = FileChangeType.Unknown;
    if (e.ChangeType == WatcherChangeTypes.Created) {
      type = (File.GetAttributes(e.FullPath) == FileAttributes.Directory)
           ? FileChangeType.NewFolder : FileChangeType.NewFile;
    }
    else if (e.ChangeType == WatcherChangeTypes.Changed) {
      // 過濾資料夾變更事件(資料夾內任何異動都會觸發)
      if (File.GetAttributes(e.FullPath) == FileAttributes.Directory) return;
      // 去重:若隊列已有同路徑 Change 事件則丟棄
      if (_queue.Any(f => f.NewPath == e.FullPath && f.Type == FileChangeType.Change)) return;
      type = FileChangeType.Change;
    }
    else if (e.ChangeType == WatcherChangeTypes.Deleted) {
      type = FileChangeType.Delete;
    }
    _queue.Enqueue(new FileChangeInfo(Guid.NewGuid(), type, e.FullPath, e.Name));
  } catch { Close(); } // 異常自動關閉,上層輪詢會重新 Open()
}

重命名事件獨立處理

private void OnFileRenamed(object sender, RenamedEventArgs e) {
  try {
    _queue.Enqueue(new FileChangeInfo(Guid.NewGuid(), FileChangeType.Rename,
      e.OldFullPath, e.FullPath, e.OldName, e.Name));
  } catch { Close(); }
}

生產級使用範例

var watcher = new FileWatcher(@"D:\Data", "*.log", true, @"D:\Log\changes.dat");
watcher.Open();

while (true) {
  if (!watcher.IsWatch) watcher.Open(); // 自動重連
  var info = watcher.Get();             // 從隊列取出事件
  if (info != null) ProcessChange(info); // 業務處理
  Thread.Sleep(1000);
}

關鍵設計亮點

  • CustomQueue<T>:執行緒安全的先進先出隊列,選擇性序列化至磁碟(應用重啟不丟事件)。
  • FileChangeInfo:統一事件模型,含 Id、Type、OldPath/NewPath、OldName/NewName。
  • 內部緩衝區:InternalBufferSize 預設 8KB,高頻目錄建議調大至 64KB (上限),並配合 NotifyFilter 精準過濾。
  • 隱藏檔案:預設監控包含隱藏/系統檔案,無需額外設定。

注意事項

  • 網路路徑監控緩衝區上限 64KB,極高併發可能丟失事件,建議本地監控 + 檔案同步工具組合。
  • 部分編輯器 (如 VS) 存檔會觸發多次 Changed,去重邏輯不可或缺。
  • 權限不足目錄會靜默失敗,建議啟動時嘗試 Directory.CreateDirectory 驗證權限。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved