filesystemwatcher常见问题包括事件触发多次、事件丢失、网络路径监控不稳定、删除文件夹时不触发内部文件事件及资源占用高;2. 解决方案是使用去抖动(debounce)机制避免重复事件,增大internalbuffersize减少事件丢失,避免监控网络路径,异步处理事件防止阻塞,添加错误处理与重试机制;3. 可通过notifyfilter精确设置监控的变更类型(如lastwrite、filename等),用filter指定文件类型,includesubdirectories控制是否监控子目录,renamed事件可获取新旧路径,enableraisingevents动态启停监控。实际使用时需结合去抖动、异步处理和合理配置以提升稳定性。

C#的
FileSystemWatcher
使用
FileSystemWatcher
FileSystemWatcher
using System;
using System.IO;
using System.Threading;
public class FileMonitor
{
private static FileSystemWatcher _watcher;
public static void StartMonitoring(string path)
{
if (!Directory.Exists(path))
{
Console.WriteLine($"错误:指定路径 '{path}' 不存在。");
return;
}
_watcher = new FileSystemWatcher(path);
// 设置要监控的变更类型
_watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName |
NotifyFilters.DirectoryName | NotifyFilters.Size;
// 监控子目录
_watcher.IncludeSubdirectories = true;
// 订阅事件
_watcher.Created += OnCreated;
_watcher.Changed += OnChanged;
_watcher.Deleted += OnDeleted;
_watcher.Renamed += OnRenamed;
_watcher.Error += OnError; // 监控内部错误
// 启用事件
_watcher.EnableRaisingEvents = true;
Console.WriteLine($"正在监控目录:{path} (按 'q' 键退出)");
// 保持程序运行,等待事件触发
while (Console.Read() != 'q') ;
}
private static void OnCreated(object sender, FileSystemEventArgs e)
{
Console.WriteLine($"创建: {e.FullPath}");
}
private static void OnChanged(object sender, FileSystemEventArgs e)
{
// 很多编辑器保存文件时会触发多次Changed事件,需要额外处理
Console.WriteLine($"修改: {e.FullPath}");
}
private static void OnDeleted(object sender, FileSystemEventArgs e)
{
Console.WriteLine($"删除: {e.FullPath}");
}
private static void OnRenamed(object sender, RenamedEventArgs e)
{
Console.WriteLine($"重命名: 旧名 '{e.OldFullPath}' -> 新名 '{e.FullPath}'");
}
private static void OnError(object sender, ErrorEventArgs e)
{
Console.WriteLine($"发生内部错误: {e.GetException().Message}");
// 错误通常是缓冲区溢出,可能需要增大InternalBufferSize
}
public static void Main(string[] args)
{
// 示例:监控当前应用程序运行目录
StartMonitoring(AppDomain.CurrentDomain.BaseDirectory);
// 或者指定一个具体路径,例如:StartMonitoring(@"C:TempMyMonitoredFolder");
}
}FileSystemWatcher
说实话,
FileSystemWatcher
一个最常见的,也是最让人困惑的,就是事件触发多次。比如你保存一个文件,
Changed
FileSystemWatcher
Created
Deleted
Changed
再比如,短时间内大量文件变动可能导致事件丢失。
FileSystemWatcher
InternalBufferSize
此外,跨网络路径监控的可靠性也值得注意。虽然
FileSystemWatcher
\ServerShareFolder
还有一个小细节,删除一个文件夹时,Deleted
Deleted
最后,就是资源占用与性能。如果你监控的目录文件数量巨大,或者变动非常频繁,
FileSystemWatcher
IncludeSubdirectories
true
FileSystemWatcher
针对上面提到的那些“坑”,我们确实需要一些策略来让
FileSystemWatcher
首先是去抖动(Debouncing)或限流(Throttling)。这是处理事件触发多次问题的核心方法。简单来说,就是当事件触发时,不要立即处理,而是设置一个短时间的延迟。如果在延迟时间内有相同的事件(比如针对同一个文件的
Changed
System.Threading.Timer
Task.Delay
// 简单的去抖动示例(概念性代码,生产环境需要更健壮的实现)
private static System.Collections.Concurrent.ConcurrentDictionary<string, DateTime> _lastEventTimes = new System.Collections.Concurrent.ConcurrentDictionary<string, DateTime>();
private static readonly TimeSpan DebounceDelay = TimeSpan.FromMilliseconds(500); // 500毫秒去抖
private static void OnChangedDebounced(object sender, FileSystemEventArgs e)
{
// 每次事件触发,更新时间戳
_lastEventTimes[e.FullPath] = DateTime.UtcNow;
// 启动一个Task,在延迟后检查是否是最后一个事件
Task.Run(async () =>
{
await Task.Delay(DebounceDelay);
if (_lastEventTimes.TryGetValue(e.FullPath, out var lastTime) &&
(DateTime.UtcNow - lastTime) >= DebounceDelay)
{
// 确认这是在延迟期后发生的最新事件
Console.WriteLine($"【去抖动后】修改: {e.FullPath}");
_lastEventTimes.TryRemove(e.FullPath, out _); // 处理完后移除
}
});
}
// 记得在FileSystemWatcher的Changed事件中调用OnChangedDebounced
// _watcher.Changed += OnChangedDebounced;其次,针对事件丢失问题,可以增加InternalBufferSize
_watcher.InternalBufferSize = 65536; // 增大缓冲区大小
另外,异步处理事件非常重要。
FileSystemWatcher
ThreadPool
Task.Run
private static void OnChangedAsync(object sender, FileSystemEventArgs e)
{
Task.Run(() =>
{
// 这里执行耗时的文件处理逻辑
Console.WriteLine($"异步处理修改: {e.FullPath}");
// 模拟耗时操作
Thread.Sleep(100);
});
}
// _watcher.Changed += OnChangedAsync;最后,不要忘了错误处理和重试机制。在事件处理代码中加入
try-catch
FileSystemWatcher
FileSystemWatcher
NotifyFilter
Filter
NotifyFilter
NotifyFilters
|
FileSystemWatcher
NotifyFilters.FileName
NotifyFilters.DirectoryName
NotifyFilters.LastWrite
NotifyFilters.LastAccess
NotifyFilters.Size
NotifyFilters.CreationTime
NotifyFilters.Attributes
NotifyFilters.Security
比如,你可能只关心文件的创建和修改,那么可以这样设置:
_watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite;
IncludeSubdirectories
true
FileSystemWatcher
false
false
Filter
Filter
"*.log"
"document*.txt"
_watcher.Filter = "*.txt"; // 只监控txt文件 // 结合NotifyFilter _watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName; _watcher.IncludeSubdirectories = false; // 只监控根目录下的txt文件修改和名称变动
事件类型(Created
Changed
Deleted
Renamed
Created
Changed
NotifyFilter
Deleted
Renamed
RenamedEventArgs
OldFullPath
FullPath
你可以根据实际需求,选择性地订阅这些事件。例如,如果你只关心新文件,那么只订阅
Created
Changed
最后,
EnableRaisingEvents
false
FileSystemWatcher
以上就是C#的FileSystemWatcher如何监控文件变更?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号