FileSystemWatcher 在没有文件名的情况下触发事件

FileSystemWatcher fires event without the file name

我有一个我喜欢的项目,我正在处理 FileSystemWatcher 让我烦恼的地方。

初始化代码如下:

for (var xx = 0; xx < _roots.Count; xx++)
{
    var watcher = new FileSystemWatcher();
    var root = _roots[xx];

    watcher.Path = root;
    // watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
    watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName;

    watcher.Filter = "*.*";
    watcher.Changed += new FileSystemEventHandler(OnChanged);
    watcher.Created += new FileSystemEventHandler(OnChanged);
    watcher.Deleted += new FileSystemEventHandler(OnChanged);
    watcher.Renamed += new RenamedEventHandler(OnRenamed);

    watcher.EnableRaisingEvents = true;

    _rootWatchers.Add(watcher);
}

假设我们正在查看的根目录 "c:\root" 有一个子目录 "c:\root\subdir",其中包含一个名为 "file1.txt".

的文件

观察者已启动 运行,我删除 "file1.txt"。当调用处理程序并检查 FileSystemEventArgs.

的值时

我希望 e.Name == "file1.txt"e.FullPath == "c:\root\subdir\file1.txt

实际值为"subdir""c:\root\subdir"

我确定这是我在某处文档中遗漏的简单内容。

你是对的,你面临的问题实际上是忘记设置 属性。

如果您设置 watcher.IncludeSubdirectories = true;,您甚至会在更深层次上收到有关文件删除的通知。

在默认模式下,FileSystemWatcher 仅记录对给定目录的更改。被建模的子目录类似于文件的目录条目,其中的任何 additions/deletions 只是直接报告为子目录的更改(如果您检查 FileSystemEventArgs.ChangeType 属性 在 OnChanged 处理程序中)。

即使您打开子目录监控,您仍然会收到 subdir 目录的更改事件 (FileSystemEventArgs.ChangeType = WatcherChangeTypes.Changed),因为当您删除其中的文件时它也会被修改.这是文件删除事件的补充。

我的测试代码:

static void Main(string[] args)
{
    var watcher = new FileSystemWatcher();

    watcher.Path = @"C:\test_dir";
    // watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
    watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName;

    watcher.Filter = "*.*";
    watcher.Changed += new FileSystemEventHandler(OnChanged);
    watcher.Created += new FileSystemEventHandler(OnChanged);
    watcher.Deleted += new FileSystemEventHandler(OnChanged);
    watcher.Renamed += new RenamedEventHandler(OnRenamed);

    watcher.IncludeSubdirectories = true;

    watcher.EnableRaisingEvents = true;

    while (true)
    {
    }
}

private static void OnRenamed(object sender, RenamedEventArgs e)
{
    Console.WriteLine($"OnRenamed: {e.FullPath}, {e.OldFullPath}");
}

private static void OnChanged(object sender, FileSystemEventArgs e)
{
    Console.WriteLine($"OnChanged: {e.ChangeType}, {e.Name}[{e.FullPath}]");
}