2012-01-28 119 views
1

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

我有一个Windows服务,它有一个FileSystemWatcher设置,我希望每次程序更新时都会FTP配置文件。已经得到了一切工作,但我注意到,不同的服务器管理器程序的行为有所不同。

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

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

什么是最好的方式来处理/ FTP这些文件时,他们真的完成保存只有一次。

我真的不想o设置一些东西来轮询filechanges的目录,每隔一段时间就会这样......而且就像每次保存配置的想法一样,我会得到一个重复的副本以及附加到日期/时间戳的附加到文件名复制到别处

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

下面是对于 “改变” 事件实际处理程序。如果第二个在700ms内,我将跳过第一个“更改”事件。但是,这并不考虑,使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); 
     } 
    } 

回答

2

我有完全相同的问题。我使用了一个将文件名映射到写入次数的HashMap,然后我使用它作为文件的查找表来检查并查看改变的事件是否已经很快应用。我定义了一些epsilon(对于我来说,确保事件被刷新大约需要2秒)。如果在地图中发现的时间比我早,我会把它放在队列中进行处理。基本上,我所要做的就是让HashMap随时更新事件和更改,并且解决了这个问题(尽管您可能需要根据您的应用程序更改您的epsilon值)。

1

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

+0

它没有杀毒软件。在某些情况下,配置程序似乎会多次保存文件。按下“确定”后,每次在表格内更新条目时,一个特定的程序会自动保存。 HashTable的想法似乎很有趣...因为每个配置文件是唯一的,我想我可以使关键字的文件名和值e.FullPath?也许使用System.Timer每10-15分钟检查一次HashTable? 我想知道有没有人在做过这种技术之前和/或是否有示例代码.... – user500741 2012-01-28 05:25:20

0

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

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