FileSystemWatcher和监视配置文件更改

时间:2012-01-28 05:03:41

标签: c# filesystemwatcher

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

我有一个Windows服务,它有一个FileSystemWatcher设置,我想在每次程序更新时FTP配置文件。我已经完成了所有工作,但我注意到不同的服务器管理器程序的行为方式不同。

保存配置文件时,FileSystemWatcher正在拾取两个“更改”事件。这导致我的程序将配置文件FTP两次,我只需要一次。

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

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

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

我已经看到很多建议谷歌搜索,甚至在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);   
       }
     }

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

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