2012-01-28 118 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

這是預期的行爲 - 所以你需要弄清楚如何在你的特定情況下處理它。

文件系統沒有「程序使用此文件」的概念。即可以編寫一個編輯器,在每次擊鍵時更新(打開/寫入/關閉)文件。文件系統會報告很多更新,但從用戶的角度來看,編輯器關閉時只有一個更新。