【问题标题】:FileSystemWatcher and Monitoring Config File ChangesFileSystemWatcher 和监控配置文件更改
【发布时间】:2012-01-28 05:03:41
【问题描述】:

我有大约 5-6 个服务器管理器程序,它们将自己的配置文件写入特定文件夹,例如 C:\ACME。配置文件都以 *ServerConfig.cfg" 结尾,其中 * = 创建它的程序名称。

我有一个具有 FileSystemWatcher 设置的 Windows 服务,我希望在每次程序更新时通过 FTP 传输配置文件。我已经让一切正常工作,但我注意到不同的服务器管理器程序的行为不同。

保存配置文件时,FileSystemWatcher 会接收两个“更改”事件。这导致我的程序将配置文件 FTP 两次,而我只需要一次。

在其他情况下,我发现它在保存配置文件时可能会创建 4、5 或 6 个“更改”事件。

当这些文件真正完成时,处理/FTP 处理这些文件的最佳方法是只保存一次。

我真的不想设置一些东西来经常轮询目录中的文件更改......并且就像每次保存配置时的想法一样,我会得到一个副本以及附加到文件名的日期/时间戳复制到别处。

我在 Google 上看到了很多建议,甚至在 Stackoverflow 上也看到了这里,但对我来说似乎没有什么是一体的。

如果队列中尚不存在“更改”事件,我想我可以将文件名放入队列中。不知道这是否是最好的近似值。

这是我的示例代码:

启动代码:

private DateTime _lastTimeFileWatcherEventRaised = DateTime.Now;

_watcherCFGFiles = new FileSystemWatcher();
_watcherCFGFiles.Path = @"C:\ACME";
_watcherCFGFiles.IncludeSubdirectories = true;
_watcherCFGFiles.Filter = "*ServerConfig.cfg";

_watcherCFGFiles.NotifyFilter = NotifyFilters.Size;
//_watcherCFGFiles.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.FileName;

_watcherCFGFiles.Changed += new FileSystemEventHandler(LogFileSystemChanges);
_watcherCFGFiles.Created += new FileSystemEventHandler(LogFileSystemChanges);
_watcherCFGFiles.Deleted += new FileSystemEventHandler(LogFileSystemChanges);
_watcherCFGFiles.Renamed += new RenamedEventHandler(LogFileSystemRenaming);
_watcherCFGFiles.Error += new ErrorEventHandler(LogBufferError);
_watcherCFGFiles.EnableRaisingEvents = true;  

这是“更改”事件的实际处理程序。如果第二个在 700 毫秒内,我将跳过第一个“更改”事件。但这并没有考虑产生 3-4 次更改事件的文件...

    void LogFileSystemChanges(object sender, FileSystemEventArgs e)
    {
        string log = string.Format("{0} | {1}", e.FullPath, e.ChangeType);

        if( e.ChangeType == WatcherChangeTypes.Changed ) 
        { 
            if(DateTime.Now.Subtract(_lastTimeFileWatcherEventRaised).TotalMilliseconds < 700) 
            { 
                return; 
            }  

           _lastTimeFileWatcherEventRaised = DateTime.Now;

           LogEvent(log);

           // Process file
           FTPConfigFileUpdate(e.FullPath);   
       }
     }

【问题讨论】:

    标签: c# filesystemwatcher


    【解决方案1】:

    我遇到了完全相同的问题。我使用了一个将文件名映射到写入时间的 HashMap,然后我将其用作文件的查找表,以检查更改的事件是否已被快速应用。我定义了一些 epsilon(对我来说,确保刷新事件大约需要 2 秒)。如果在地图中找到的时间早于该时间,我会将其放入队列中以进行处理。基本上我所要做的就是让 HashMap 与事件和更改保持同步,这很有效(尽管您可能希望根据您的应用程序更改您的 epsilon 值)。

    【讨论】:

      【解决方案2】:

      这是正常现象,因为防病毒系统或其他程序在文件更改内容时会进行更多写入。我通常创建一个(全局)HashTable 并检查文件名是否存在,如果不存在,则将文件名放入其中并启动并在 3-5 秒后执行异步操作以删除文件名。

      【讨论】:

      • 它没有杀毒软件。在某些情况下,配置程序似乎多次保存文件。每次在按“确定”后更新表格中的条目时,一个特定的程序似乎会自动保存。 HashTable 的想法似乎很有趣……因为每个配置文件都是唯一的,我想我可以将键设为文件名,将值设为 e.FullPath?也许使用 System.Timer 每 10-15 分钟检查一次 HashTable?我想知道是否有人以前做过这种技术和/或是否有示例代码....
      【解决方案3】:

      这是预期的行为 - 因此您需要弄清楚如何在您的特定情况下处理它。

      文件系统没有“程序完成使用此文件”的概念。 IE。可以编写在每次击键时更新(打开/写入/关闭)文件的编辑器。文件系统会报告很多更新,但是从用户的角度来看,关闭编辑器时只有一次更新。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-03
        • 2012-05-08
        相关资源
        最近更新 更多