为何在Beyond Compare中保存修改未触发FileSystemWatcher Changed事件?
我之前也碰到过一模一样的问题!其实核心原因在于不同编辑器的文件保存机制差异,导致FileSystemWatcher接收到的系统通知完全不一样。
问题根源
FileSystemWatcher是依赖Windows操作系统的ReadDirectoryChangesW API提供的文件系统通知来工作的。而Beyond Compare和Notepad++的保存逻辑有着本质区别:
- Notepad++这类编辑器是直接打开原文件,修改内容后直接写入覆盖原文件,这种操作会触发
Changed事件。 - Beyond Compare默认使用**原子保存(Atomic Save)**机制:它会先在同一目录下创建一个临时隐藏文件(比如带
.tmp或.bak后缀),把修改后的内容写入临时文件,接着删除原文件,最后把临时文件重命名为原文件的名字。对系统来说,这是「删除旧文件+创建新文件」的操作,所以会触发Deleted和Created事件,但不会触发Changed事件——因为原文件根本没被修改,而是被完全替换了。
你可以简单验证这个逻辑:打开Beyond Compare保存文件后,开启文件夹的「显示隐藏文件」选项,大概率能看到它生成的临时文件痕迹;或者在你的FileSystemWatcher代码里同时监听Created和Deleted事件,会发现这两个事件会成对触发。
解决办法
针对这个情况,有两种常用的处理方式:
- 同时监听多事件并做合并处理
在代码里除了监听Changed事件,还要加上Created和Deleted事件的监听。可以维护一个短时间内的「最近删除文件列表」,当收到Created事件时,检查是否刚有同名文件被删除,如果符合,就把这个操作视为「文件被修改」,执行和Changed事件一致的处理逻辑。 - 修改Beyond Compare的保存设置
打开Beyond Compare的设置面板,找到「文件操作」相关选项,部分版本可以关闭原子保存功能,改为直接覆盖原文件。不过要注意:原子保存的设计是为了避免保存过程中程序崩溃导致原文件损坏,关闭后会增加这类风险。
内容的提问来源于stack exchange,提问作者Dean
相关产品推荐
相关产品推荐

