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);
}
Id、Type、OldPath/NewPath、OldName/NewName。InternalBufferSize 預設 8KB,高頻目錄建議調大至 64KB (上限),並配合 NotifyFilter 精準過濾。Changed,去重邏輯不可或缺。Directory.CreateDirectory 驗證權限。