C# FileWatcher如何仅监控指定一级子目录?
如何让FileWatcher仅监控一级子目录并排除二级目录?
你现在遇到的问题是因为设置了IncludeSubdirectories = true后,FileSystemWatcher会递归监控所有层级的子目录,所以二级目录里的sample.mkv也会触发Created事件。我给你两种实用的解决思路,你可以根据自己的场景选择:
方案一:给每个一级子目录单独创建Watcher(推荐)
这种方法最直接也最高效——我们不启用全局的子目录递归,而是手动枚举主目录下的所有一级子目录,给每个子目录单独配一个Watcher,每个Watcher只监控当前目录(不深入子目录)。
具体实现代码
string mainFolderPath = @"你的mainFolder路径"; // 存储所有Watcher实例,方便后续管理(比如程序退出时释放资源) List<FileSystemWatcher> watchers = new List<FileSystemWatcher>(); // 获取mainFolder下的所有一级子目录 var firstLevelSubDirs = Directory.GetDirectories(mainFolderPath); foreach (var subDir in firstLevelSubDirs) { var dirWatcher = new FileSystemWatcher(subDir) { Filter = "*.mkv", // 只监控文件名和创建时间,减少不必要的事件触发 NotifyFilter = NotifyFilters.FileName | NotifyFilters.CreationTime, // 默认就是false,不用额外设置,确保不监控子目录 // IncludeSubdirectories = false }; // 绑定创建事件 dirWatcher.Created += OnFirstLevelFileCreated; // 别忘了绑定错误事件,处理权限等异常 dirWatcher.Error += OnWatcherError; dirWatcher.EnableRaisingEvents = true; watchers.Add(dirWatcher); } // 自定义的文件创建事件处理方法 private void OnFirstLevelFileCreated(object sender, FileSystemEventArgs e) { // 这里只会触发一级子目录下的.mkv文件事件 Console.WriteLine($"检测到目标文件:{e.FullPath}"); } private void OnWatcherError(object sender, ErrorEventArgs e) { Console.WriteLine($"监控器出错:{e.GetException().Message}"); }
额外提醒
如果你的一级子目录是动态创建的(比如运行过程中会新增subfolder3),那还需要给mainFolder再加一个Watcher,监控目录创建事件,当新的一级子目录出现时,自动添加对应的Watcher实例。
方案二:在事件中过滤目录层级
如果你不想维护多个Watcher,也可以保留IncludeSubdirectories = true,但在Created事件里判断文件所在的目录层级,只处理一级子目录下的文件。
具体实现代码
string mainFolderPath = @"你的mainFolder路径"; var mainWatcher = new FileSystemWatcher(mainFolderPath) { Filter = "*.mkv", IncludeSubdirectories = true, NotifyFilter = NotifyFilters.FileName | NotifyFilters.CreationTime }; mainWatcher.Created += (sender, e) => { // 获取文件所在的目录路径 string fileDir = Path.GetDirectoryName(e.FullPath); // 计算该目录相对于mainFolder的相对路径 string relativeDir = Path.GetRelativePath(mainFolderPath, fileDir); // 分割路径,统计目录层级(一级子目录的相对路径分割后长度为1) int dirLevel = relativeDir.Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries).Length; // 只处理一级子目录下的文件 if (dirLevel == 1) { Console.WriteLine($"检测到一级子目录的文件:{e.FullPath}"); } // 二级及以上目录的文件直接忽略 }; mainWatcher.EnableRaisingEvents = true;
方案对比
- 方案一:更高效,不会监控二级目录,减少无用的事件触发,适合目录结构相对稳定的场景。
- 方案二:代码更简洁,但本质上还是会监控所有子目录,只是在事件里过滤,适合快速实现或者需要动态监控新增一级子目录的场景。
内容的提问来源于stack exchange,提问作者RedP1ll
相关产品推荐
相关产品推荐

