【问题标题】:FileSystemWatcher fires event without the file nameFileSystemWatcher 触发没有文件名的事件
【发布时间】:2018-01-12 05:29:28
【问题描述】:

我有一个我正在做的宠物项目,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"

我确定这是我在某个地方的文档中遗漏的一些简单的东西。

【问题讨论】:

  • 我认为这可能会有所帮助:stackoverflow.com/questions/11255360/…
  • 这是我在提出问题之前在 FileSystemWatcher 上阅读的第一个问题。它没有帮助,因为它涵盖了使用 NameFullName 的实例属性来获取信息。这个问题是关于返回目录信息而不是文件信息的事件。
  • 如果我现在靠近键盘,我会尝试一个想法:设置一个测试,只对一个路径进行删除监控。如果文件详细信息符合预期,请添加其余的复杂性以查看代码示例中的其他任何内容是否导致问题。我看到的每篇关于文件观察器的文章都表明应该报告文件路径(我认为是相对路径)。也许您将多个事件处理程序映射到同一个方法会使您的水浑浊。只是一个猜测。我会进行一些测试,但我在手机自动取款机上

标签: c# .net filesystemwatcher


【解决方案1】:

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

如果您设置watcher.IncludeSubdirectories = true;,即使在更深的级别,您也会收到有关文件删除的通知。

在默认模式下,FileSystemWatcher 仅记录对给定目录的更改。子目录被建模为类似于文件的目录条目,其中的任何添加/删除都将直接报告为对子目录的更改(如果您检查了FileSystemEventArgs.ChangeType 处理程序中的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}]");
}

【讨论】:

  • 我上面的测试将 IncludeSubdirectories 设置为 true,如果 OnChanged 事件已连接,我仍然会在 OnDeleted 事件中获得丢失的文件路径。
  • @JM 您能否更具体地了解您的操作系统和 .NET 版本?它适用于 Win10 和 .NET Framework 4.7.1。我已经包含了我使用的代码。
  • 我的操作系统和 .NET 版本也是 Win 10 和 .NET 4.7.1。我将再次运行以仔细检查我的 100% 确定。我也会运行你的并进行比较。
  • @JM 您的代码也适用于我。输出:Watcher_Deleted C:\Temp\Root\subdir\test_file.txt Watcher_Changed C:\Temp\Root\subdir.
  • 当我运行你的时,我得到: OnChanged: Created, subdir\New Text Document.txt[C:\test_dir\subdir\New Text Document.txt] OnChanged: Changed, subdir\New Text Document。 txt[C:\test_dir\subdir\New Text Document.txt] OnChanged:已更改,subdir[C:\test_dir\subdir] OnChanged:已删除,subdir\New Text Document.txt[C:\test_dir\subdir\New Text Document .txt] OnChanged:已更改,子目录 [C:\test_dir\subdir]。那是为了创建一个文本文件,然后删除该文件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多