Richie

Sometimes at night when I look up at the stars, and see the whole sky just laid out there, don't you think I ain't remembering it all. I still got dreams like anybody else, and ever so often, I am thinking about how things might of been. And then, all of a sudden, I'm forty, fifty, sixty years old, you know?

[ IO.File ] FileSystemWatcher

    示例:
    1. BufferSize
    Windows操作系统使用FileSystemWatcher创建的一个内存缓冲区通知程序文件的修改信息,如果在很短的时间内有非常多的文件修改,这个缓冲区会溢出, 造成部分追踪丢失,并且FileSystemWatcher不会产生异常。加大InternalBufferSize属性值可以避免这种情况。
    InternalBufferSize默认值是8K,可以设置的最小值是4K,增加或减小InternalBufferSize最好用4K的整数倍。每一个事件通知需要使用16字节,并不包含文件名。InternalBufferSize的内存来自non-paged内存,注意这部分内存资源比较宝贵。
    使用NotifyFilter、IncludeSubdirectories属性减小trace范围,设置filter属性并不会影响进入缓冲区的事件通知,另外尽快的完成事件处理,也是避免缓冲区溢出造成事件丢失的一个措施。
    2. 隐藏文件也会监控
    3. 有些系统中,FileSystemWatcher的事件里对长文件名使用8.3短文件名方式表示。
    4. 如果多个FileSystemWatcher在监控同一个对象,在Windows XP在没有打SP1之前,Windows 2000 SP2或之前的操作系统中,只会有一个FileSystemWatcher接收到通知;更新版本的操作系统中所有FileSystemWatcher都会收到通知。
    5. 一次文件操作产生多个事件通知
    某些文件操作可能会引发多个文件更改事件,例如新增文件、拷贝粘贴一个新的文件等。上面的示例代码使用log4net记录日志,用一个计数器记录事件编号,当Copy一个xml文件并粘贴到c:\t目录下时,从日志文件中可以看到会产生多个事件:一个Created和多个Changed。微软的解释是文件系统的操作比较复杂,另外还有其它程序的影响(例如杀毒软件等)。
    初步测试,Rename、Delete、New只会触发一个事件,Save、Paste时会有多个事件。
    在某些项目中经常需要监控某个配置文件的修改,实时加载配置信息到程序中,这种情况下可以参考log4net的做法。通过一个计时器,在文件事件处理中让计时器延迟一段时间之后,再执行加载新的配置文件操作。这样可以避免对文件做一次操作触发了多个更改事件,而多次加载配置文件。示例如下:
    上面例子用log4net分别记录了FileSystemWatcher事件和Timer的Change事件,这样可以做一个简单的分析。
    操作如下:对一个文件重命名,拷贝粘贴一个文件,打开一个文件进行修改后保存,选择2个文件删除,记录的log如下:
2006-12-16 22:50:07,828 [2904] - FileEvent 01 : Renamed - Old Path : c:\t\a.xml New Path : c:\t\b.xml
2006-12-16 22:50:08,359 [3828] - TimerEvent 01
2006-12-16 22:50:49,171 [2904] - FileEvent 02 : Created - c:\t\Copy of b.xml
2006-12-16 22:50:49,171 [2904] - FileEvent 03 : Changed - c:\t\Copy of b.xml
2006-12-16 22:50:49,171 [2904] - FileEvent 04 : Changed - c:\t\Copy of b.xml
2006-12-16 22:50:49,671 [3828] - TimerEvent 02
2006-12-16 22:51:02,312 [2904] - FileEvent 05 : Changed - c:\t\1.xml
2006-12-16 22:51:02,312 [2904] - FileEvent 06 : Changed - c:\t\1.xml
2006-12-16 22:51:02,812 [3828] - TimerEvent 03
2006-12-16 22:51:15,250 [2904] - FileEvent 07 : Deleted - c:\t\1.xml
2006-12-16 22:51:15,250 [2904] - FileEvent 08 : Deleted - c:\t\Copy of b.xml
2006-12-16 22:51:15,750 [3828] - TimerEvent 04
    可以看到,一个文件操作引起多个文件更改事件时,Timer的Change事件都只执行了一次。
    6. 有人想同时监控多种类型的文件,例如*.xml + *.config,发现Filter属性不支持这种设置(只能够设置一种)。
    这种情况下可以将Filter属性设成*.*,在事件里用if (e.FullPath.EndsWith(".xml") || e.FullPath.EndsWith(".config"))自己判断过滤一下。记得Filter属性的设置并不会减少进入缓冲区的事件通知,因此上面的方法并不会带来多少性能损失。

posted on 2006-12-16 23:27  riccc  阅读(5091)  评论(3编辑  收藏  举报

导航