使用FileSystemWatcher監視文件變化


本文轉載:http://www.cnblogs.com/zanxiaofeng/archive/2011/01/08/1930583.html

FileSystemWatcher基礎

屬性:

    Path——這個屬性告訴FileSystemWatcher它需要監控哪條路徑。例如,如果我們將這個屬性設為“C:\test”,對象就監控test目錄下所有文件發生的所有改變(包括刪除,修改,創建,重命名)。

    IncludeSubDirectories——這個屬性說明FileSystemWatcher對象是否應該監控子目錄中(所有文件)發生的改變。

    Filter——這個屬性允許你過濾掉某些類型的文件發生的變化。例如,如果我們只希望在TXT文件被修改/新建/刪除時提交通知,可以將這個屬性設為“*txt”。在處理高流量或大型目錄時,使用這個屬性非常方便。

NotifyFilter——獲取或設置要監視的更改類型。可以進一步的過濾要監控的更改類型,如watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite

           | NotifyFilters.FileName | NotifyFilters.DirectoryName;

事件:

    Changed——當被監控的目錄中有一個文件被修改時,就提交這個事件。值得注意的是,這個事件可能會被提交多次,即使文件的內容僅僅發生一項改變。這是由於在保存文件時,文件的其它屬性也發生了改變。

    Created——當被監控的目錄新建一個文件時,就提交這個事件。如果你計划用這個事件移動新建的事件,你必須在事件處理器中寫入一些錯誤處理代碼,它能處理當前文件被其它進程使用的情況。之所以要這樣做,是因為Created事件可能在建立文件的進程釋放文件之前就被提交。如果你沒有准備正確處理這種情況的代碼,就可能出現異常。

    Deleted——當被監控的目錄中有一個文件被刪除,就提交這個事件。

    Renamed——當被監控的目錄中有一個文件被重命名,就提交這個事件。 

 

注:如果你沒有將EnableRaisingEvents設為真,系統不會提交任何一個事件。如果有時FileSystemWatcher對象似乎無法工作,請首先檢查EnableRaisingEvents,確保它被設為真。

問題:

  程序里需要監視某個目錄下的文件變化情況: 一旦目錄中出現新文件或者舊的文件被覆蓋,程序需要讀取文件內容並進行處理;但在實際處理中發現當一個文件產生變化時,Change事件被反復觸發了好幾次。這樣可能的結果是造成同一文件的重復處理。
解決方法:

  針對上面的問題,於是寫了一個可以延遲FileSystemWatcher發出的事件的Class DelayFileSystemWatcher。

復制代碼
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;

namespace Utility
{
public class DelayFileSystemWatcher
{
private readonly Timer m_Timer;
private readonly Int32 m_TimerInterval;
private readonly FileSystemWatcher m_FileSystemWatcher;
private readonly FileSystemEventHandler m_FileSystemEventHandler;
private readonly Dictionary<String, FileSystemEventArgs> m_ChangedFiles = new Dictionary<string, FileSystemEventArgs>();

public DelayFileSystemWatcher(string path, string filter, FileSystemEventHandler watchHandler, int timerInterval)
{
m_Timer = new Timer(OnTimer, null, Timeout.Infinite, Timeout.Infinite);
m_FileSystemWatcher = new FileSystemWatcher(path, filter);
m_FileSystemWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.CreationTime;
m_FileSystemWatcher.Created += fileSystemWatcher_Changed;
m_FileSystemWatcher.Changed += fileSystemWatcher_Changed;
m_FileSystemWatcher.Deleted += fileSystemWatcher_Changed;
m_FileSystemWatcher.Renamed += fileSystemWatcher_Changed;
m_FileSystemWatcher.EnableRaisingEvents = true;
m_FileSystemEventHandler = watchHandler;
m_TimerInterval = timerInterval;
}

public void fileSystemWatcher_Changed(object sender, FileSystemEventArgs e)
{
lock (m_ChangedFiles)
{
if (!m_ChangedFiles.ContainsKey(e.Name))
{
m_ChangedFiles.Add(e.Name, e);
}
}
m_Timer.Change(m_TimerInterval, Timeout.Infinite);
}

private void OnTimer(object state)
{
Dictionary<String, FileSystemEventArgs> tempChangedFiles = new Dictionary<String, FileSystemEventArgs>();

lock (m_ChangedFiles)
{
foreach (KeyValuePair<string, FileSystemEventArgs> changedFile in m_ChangedFiles)
{
tempChangedFiles.Add(changedFile.Key, changedFile.Value);
}
m_ChangedFiles.Clear();
}

foreach (KeyValuePair<string, FileSystemEventArgs> changedFile in tempChangedFiles)
{
m_FileSystemEventHandler(this, changedFile.Value);
}
}
}
}
復制代碼

使用方式如下:

復制代碼
        s_DelayFileSystemWatcher = new DelayFileSystemWatcher(@"C:\Temp", "*.xml", fileSystemWatcher_Changed, 1500);

private static void fileSystemWatcher_Changed(object sender, FileSystemEventArgs e)
{
switch (e.ChangeType)
{
case WatcherChangeTypes.Created:
//TODO
break;
case WatcherChangeTypes.Deleted:
//TODO
break;
case WatcherChangeTypes.Changed:
//TODO
break;
default:
break;
}
}
復制代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM