如何获取FileSystemWatcher事件的更多详细信息及文件操作完成状态?
解决FileSystemWatcher重复事件与增强信息的方案
一、抑制重复事件
FileSystemWatcher触发多次重复事件,本质是Windows文件操作会产生多个底层通知(比如创建临时文件、写入内容、重命名最终文件等),可以通过延迟去重处理:
private readonly HashSet<string> _pendingFiles = new HashSet<string>(); private readonly Timer _processTimer = new Timer(1000); // 1秒延迟,可根据场景调整 public void InitWatcher() { var watcher = new FileSystemWatcher(@"C:\YourTargetFolder"); watcher.Created += OnFileTriggered; watcher.Changed += OnFileTriggered; _processTimer.Elapsed += ProcessPendingFiles; _processTimer.Start(); } private void OnFileTriggered(object sender, FileSystemEventArgs e) { lock (_pendingFiles) { _pendingFiles.Add(e.FullPath); } } private void ProcessPendingFiles(object sender, ElapsedEventArgs e) { List<string> targetFiles; lock (_pendingFiles) { targetFiles = _pendingFiles.ToList(); _pendingFiles.Clear(); } foreach (var file in targetFiles) { if (IsFileCompleted(file)) { // 执行你的业务逻辑 Console.WriteLine($"处理就绪文件:{file}"); } else { // 文件未就绪,放回待处理队列 lock (_pendingFiles) { _pendingFiles.Add(file); } } } }
二、判断文件是否完成写入/下载
核心逻辑是检查文件是否处于锁定状态——下载或复制过程中文件会被写入进程占用,无法独占访问:
private bool IsFileCompleted(string filePath) { if (!File.Exists(filePath)) return false; try { // 尝试以独占读写模式打开文件,成功则说明文件已释放 using (var stream = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) { return true; } } catch (IOException) { // 文件被锁定,仍在写入 return false; } }
也可以结合文件大小稳定性判断:记录文件初始大小,延迟后再次检查,若连续两次大小一致,说明写入完成。
三、获取更详细的变更信息
1. 精准区分变更类型
结合ChangeType和文件状态判断真实操作:
- 最终文件创建:
Created事件触发后,通过IsFileCompleted验证通过,判定为文件下载/存入完成。 - 完成的修改:
Changed事件触发时,文件可访问且大小稳定,说明是已完成的内容修改。 - 重命名操作:监听
Renamed事件,它会提供OldFullPath和FullPath,直接明确重命名动作。
2. 读取文件详细属性
在文件就绪后,直接读取文件元数据获取额外信息:
var fileInfo = new FileInfo(filePath); Console.WriteLine($"文件大小:{fileInfo.Length} 字节"); Console.WriteLine($"最后写入时间:{fileInfo.LastWriteTime}"); Console.WriteLine($"文件所有者:{fileInfo.GetAccessControl().GetOwner(typeof(System.Security.Principal.NTAccount))}");
四、进阶优化
- 过滤临时文件:忽略
.tmp、.part等临时后缀的文件,减少无效事件触发。 - 底层API调用:如果需要更精细的通知,可通过P/Invoke调用Windows原生的
ReadDirectoryChangesWAPI,它能返回更底层的文件操作细节(如具体的写入、删除动作),但实现复杂度更高。
内容的提问来源于stack exchange,提问作者TryingToLearn
相关产品推荐
相关产品推荐

