如何解决处理目录现有文件与启动FileSystemWatcher的文件遗漏问题
修复方案
你当前的实现漏洞来自全量扫描现有文件和启动目录监听两个动作的执行顺序颠倒,导致中间时间差内新增的文件没有被任何逻辑捕获,按以下方案修改即可解决:
- 先启动
FileSystemWatcher监听,再执行全量文件遍历,彻底消除时间差盲区 - 新增已处理文件幂等校验逻辑,避免同个文件被全量遍历逻辑和监听事件重复处理
优化后代码示例
using System.Collections.Concurrent; var dirPath = "myDir"; // 线程安全字典记录已处理文件,用于去重 var processedFiles = new ConcurrentDictionary<string, bool>(); // 先启动监听,再处理存量文件,避免时间差漏单 var watcher = new FileSystemWatcher(dirPath); watcher.Created += (sender, e) => { // 仅未处理过的文件执行处理逻辑 if (processedFiles.TryAdd(e.FullPath, true)) { Process(e.FullPath); // 业务可自行加逻辑,定期清理processedFiles中的旧记录避免内存溢出 } }; watcher.EnableRaisingEvents = true; // 处理现有存量文件 foreach (var file in Directory.EnumerateFiles(dirPath)) { if (processedFiles.TryAdd(file, true)) { Process(file); } }
可选优化
如果涉及大文件写入场景,可能出现文件还在写入中就被触发处理的情况,可新增文件就绪判断逻辑:
// 判断文件是否已经写完、可以正常读取 private bool IsFileAvailable(string filePath) { try { using var fs = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.None); return true; } catch (IOException) { // 文件还被占用,说明还在写入中 return false; } }
在调用Process方法前先判断文件是否就绪即可。
内容的提问来源于stack exchange,提问作者Anatoliy
相关产品推荐
相关产品推荐

