我使用.Net FileSystemWatcher编写了一个小型测试应用程序,以便密切关注目录。当我将一个大型(几个Mb)文件复制到该目录中时,我会列出以下事件(请参阅屏幕截图 - 并忽略删除事件开始)。
alt text http://robinwilson.homelinux.com/FSW.png
我得到了一个已创建的事件(如预期的那样),但后来又发生了两个事件(相隔大约0.7秒)。为什么是这样?这会导致我计划开发的应用程序出现重大问题 - 因为我会尝试用文件做两次事情(大概是在它写完之前一次!)。有什么办法可以阻止这种情况发生吗?从我在StackOverflow和其他地方读到的内容来看,一旦文件被更改然后关闭,您应该只获得一个更改的事件。我为什么要两个?
答案 0 :(得分:11)
根据documentation(参见事件和缓冲区大小下的第一个项目符号点):
公共文件系统操作可能会引发多个事件。例如,当文件从一个目录移动到另一个目录时,可能会引发多个OnChanged和一些OnCreated和OnDeleted事件。 移动文件是一项复杂的操作,由多个简单操作组成,因此会引发多个事件。同样,某些应用程序(例如,防病毒软件)可能会导致FileSystemWatcher检测到其他文件系统事件。 / p>
答案 1 :(得分:2)
通常复制程序是以块为单位进行的,而不是一次完成整个文件。我不认为你可以做任何事情来避免这种情况,你必须采用你的算法来解决这个问题。
您可以尝试打开具有独占读取权限的文件,只有在其他程序完成复制和关闭文件时才应授予您的程序。否则,您将获得IOException,您可以等待下一次更改。但这并不意味着你不应该处理多重变化事件。在记事本中打开文本文件并偶尔保存一次将生成更改事件,但文件不会一直被锁定。
另一种方法是在一段时间内收集触摸的文件,当FileSystemWatcher停止生成事件时,立即处理所有文件。