【问题标题】:Cannot monitor word docs using FileSystemWatcher无法使用 FileSystemWatcher 监控 word 文档
【发布时间】:2011-09-27 04:20:28
【问题描述】:

我有一个包含多个 word 文档的文件夹。我需要监视此文件夹以了解这些 Word 文档中的任何更改。我面临以下问题:

  1. FileSystemWatcher 从不报告正在更改的文件的确切名称。例如,对于文件 abc.doc,它会在第一次保存时报告“~$abc.doc is changed”。
  2. 对于该文件的所有后续保存,不会调用以下代码中的OnChanged 事件。当我将过滤器更改为watcher.Filter = "*.*"时,我发现对于后续保存,它会报告“~WRL0001.tmp is changed”。

所以底线是我永远不知道更改文件的确切名称。

我正在使用以下代码

public static void Main()
{
    FileSystemWatcher watcher = new FileSystemWatcher();
    watcher.Path = @"C:\Users\Administrator\Documents\"; //"
    watcher.NotifyFilter = NotifyFilters.Size;
    watcher.Filter = "*.doc";
    watcher.Changed += new FileSystemEventHandler(OnChanged);

    watcher.EnableRaisingEvents = true;

    Console.WriteLine("Press \'q\' to quit the sample.");
    while (Console.Read() != 'q') ;
}

private static void OnChanged(object source, FileSystemEventArgs e)
{
    Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType);
}

【问题讨论】:

  • Win7/Vista 上的 FSW 似乎有点无聊,因为我一直无法让它正常工作:\ 无论如何,我所做的是文件名的 HashMap 以更改日期并扫描目录一次过一会儿,检查一切。我尝试了 C++ ReadDirectoryChanges 和同样的问题....
  • @Leon 这个链接太糟糕了...我首先必须使用 Microsoft 帐户登录,当我这样做时(可能是错误的类型,因为它不是开发人员帐户)我被微软告知没有找到该网站。能否请您提供另一个链接?

标签: c# .net vb.net filesystems filesystemwatcher


【解决方案1】:

文件系统观察者从不报告正在执行的文件的确切名称 改变了。例如,对于文件 abc.doc,它报告“~$abc.doc is 更改”在第一次保存时。

这样做的原因是 Word 在打开原始文件的当前目录中创建了几个临时文件,并且在创建新文件时也会触发 FileChanged 事件。实际上,FileSystemWatcher 会触发 FileCreated,然后触发 FileChanged 事件。由于您没有订阅 FileCreated,因此您只会看到 FileChanged 通知。

对于该文件的所有后续保存,OnChanged 事件在 未调用以下代码。当我将过滤器更改为 watcher.Filter = ".",我发现对于后续的保存,它会报告 “~WRL0001.tmp 已更改”。

同上。

但我对你的问题很好奇,我对你的程序做了一点改动,并修改如下(只发布相关行):

watcher.NotifyFilter =   NotifyFilters.Attributes;
watcher.Filter = "*.doc";
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.EnableRaisingEvents = true;

然后我看到保存文件时在控制台上打印了正在更改的文件的实际名称。当我查看原始文档中的哪些属性从一次保存到下一次保存时发生了变化,我注意到修订号增加了 1(我知道,从操作系统的角度来看,修订号不是文件属性)。我确信其他属性——因为没有更好的词——已经改变了。如果您想将 NotificationFilter 设置为 NotifyFilters.Attributes; 以使其工作,这取决于您,但如果使用 NotificationFilter =NotifyFilters.Size | NotifyFilters.LastWrite; 则它肯定不起作用。

【讨论】:

  • 其实是因为它是重命名而不是更改事件see here
【解决方案2】:

保存为随机文件名是为了保持文件更改操作的原子性并避免在写入失败时破坏用户数据。

通常的顺序:

  • 打开文件“myfile.ext”
  • 编辑
  • 将更改文件写入同一文件夹中的“some_temp_name”
  • 如果写入成功,将“myfile.ext”重命名为“myfile.old”,将“some_temp_name”重命名为“myfile.ext”。

根据程序,顺序可能不同 - 即最后重命名可能是文件复制或删除原始文件。您必须注意目标文件夹中的所有类型的更改,并观察您感兴趣的文件的最终更新(可能是创建通知而不是更改)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-08
    • 2016-10-16
    • 1970-01-01
    • 1970-01-01
    • 2013-02-07
    相关资源
    最近更新 更多