我有问题。我在FileSystemWatcher
上编写了一个包装器,用于检测 root 文件夹及其所有子文件夹中的更改。没什么好看的:
FileSystemWatcher watcher = new FileSystemWatcher ();
watcher.Path = this.Root;
watcher.IncludeSubdirectories = true;
watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.LastAccess | NotifyFilters.DirectoryName | NotifyFilters.FileName;
watcher.Changed += new FileSystemEventHandler (watcher_Changed);
watcher.Deleted += new FileSystemEventHandler (watcher_Deleted);
watcher.Created += new FileSystemEventHandler (watcher_Created);
watcher.Renamed += new RenamedEventHandler (watcher_Renamed);
watcher.EnableRaisingEvents = true;
在.NET中,在Windows下,它就像一个魅力。但是当我将代码移植到mono并在OSX下运行代码时,它只能在根文件夹中正常工作。
我现在注意到的问题:
在观察者启动时,根目录下已存在的文件夹内的操作不会引发事件
我通过EventArgs.FullPath
属性获取的路径不正确(当我将文件复制到path_to_root / some / more / subdirs / some.file时,我得到的路径只是path_to_root / some.file)
一年前已经报道了unproper路径的问题(看起来已经解决了)但是我的单声道来自去年12月(MonoDevelop在参考资料部分说它是版本4.0.0.0,我只能说关于分发)和错误仍在那里...... 看到: https://bugzilla.xamarin.com/show_bug.cgi?id=5747
有什么想法吗?我真的很好奇,如果有一个解决方法,不需要编写自己的观察者重复轮询文件系统或为 root 下的每个文件夹启动单独的观察者...
提前致谢!
答案 0 :(得分:5)
据我所知,这根本不适用于OS X上的Mono。我上周遇到过它并且找不到任何错误报告,所以我在这里报告:https://bugzilla.xamarin.com/show_bug.cgi?id=16259
就我可以遵循implementation of KEventWatcher而言,在创建观察者时,它不会对订阅子目录做任何事情。我认为它订阅子目录的唯一时间是它检测到它们是在PostEvent中添加的。即使它在创建时订阅了所有子目录,也可能不是一个很好的解决方案。底层的kevent机制需要为每个子目录打开一个文件描述符,这可能最终成为很多文件描述符。
Mono确实有FileSystemWatcher的其他实现,但我相信在编译时,实现的选择会被融入Mono运行时。有一个缓慢且低效的默认观察程序可以在所有平台上运行,只需每隔一秒左右扫描整个目录树,但只有在没有特定于平台的实现时才会选择它。
我不敢说,看起来你最好的选择是你建议的解决方法 - 手动扫描更改或为每个目录创建FileSystemWatcher。