5

我有个问题。我已经编写了一个包装器FileSystemWatcher来检测文件夹及其所有子文件夹中的更改。没有什么花哨:

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 下,它就像一个魅力。但是当我将代码移植到单声道并在 OSX 下运行代码时,它只能在根文件夹中正常工作。

我现在注意到的问题:

  • 在观察者启动时,不会为根目录下已存在的文件夹中的操作引发事件

  • 我通过EventArgs.FullPath属性获得的路径不正确(当我将文件复制到 path_to_root/some/more/subdirs/some.file 时,我得到的路径只是 path_to_root/some.file)。

一年前已经报告了不正确路径的问题(看起来已经解决了),但我的单声道来自去年 12 月(MonoDevelop 在参考部分中说它是版本 4.0.0.0,这就是我能说的关于分发的全部内容) 并且错误仍然存​​在...请参阅: https ://bugzilla.xamarin.com/show_bug.cgi?id=5747

有任何想法吗?我真的很好奇是否有一种解决方法不需要编写自己的观察程序来重复轮询文件系统或为目录下的每个文件夹启动单独的观察程序......

提前致谢!

4

1 回答 1

5

据我所知,这在 OS X 上的 Mono 中根本不起作用。我上周遇到了它,找不到任何错误报告,所以我在这里报告了它:https ://bugzilla.xamarin.com/show_bug .cgi?id=16259

据我所知 KEventWatcher 的实现,在创建观察者时它不会做任何事情来订阅子目录。我认为它订阅子目录的唯一时间是当它检测到它们被添加到 PostEvent 中时。即使它确实订阅了创建时的所有子目录,它也可能不是一个很好的解决方案。底层的 kevent 机制需要每个子目录都有一个打开的文件描述符,这最终可能会成为大量的文件描述符。

Mono 确实有 FileSystemWatcher 的其他实现,但我相信实现的选择会在 Mono 运行时被编译。有一个缓慢而低效的默认观察程序,它通过简单地每秒钟左右扫描整个目录树就可以在所有平台上工作,但只有在没有特定于平台的实现可用时才会选择它。

恐怕要说,看起来您最好的选择是您建议的解决方法之一 - 手动扫描更改或为每个目录创建 FileSystemWatcher。

于 2013-11-19T11:05:57.240 回答