摘要:FileSystemWatcher 類別應用實例
身為一個程式設計人員免不了的就是對檔案系統的操作(包括:檔案建立、刪除、捕捉特定目錄或檔案的事件),筆者最近常在程式設計論壇看到網友提出一些監控檔案系統的相關問題,如果說到要在.NET中對檔案系統進行監控,那就非了解FileSystemWatcher類別不可了,今天筆者就對FileSystemWatcher這個類別來為各位解說。
列舉三個網友常問的問題:
- 如何在有效率的監控某個目錄或檔案是否有變更?
- 如何使用C#監控目錄改變?
- 如何監控一個目錄的文件是否發生改變?
FileSystemWatcher 事件
名稱 | 說明 | |
Changed | 發生在指定 Path 內的檔案或目錄變更時。 | |
Created | 發生在指定 Path 內的檔案或目錄建立時。 | |
Deleted | 發生在指定 Path 內的檔案或目錄刪除時。 | |
Error | 發生在內部緩衝區溢位時。 | |
Renamed | 發生在指定的 Path 內的檔案或目錄重新命名時 |
範例一、監看C:\是否有檔案或目錄被刪除。
using System.IO;
static void Main(string[] args)
{
FileSystemWatcher fsw = new FileSystemWatcher(@"C:\");
//不監控指定目錄內的子目錄,以免捕捉到太多系統運作的訊息,當然您也可以是個人情況而開啟。
fsw.IncludeSubdirectories = false;
fsw.Deleted += new FileSystemEventHandler(fsw_Deleted);
fsw.EnableRaisingEvents = true;
Console.Read();
}
static void fsw_Deleted(object sender, FileSystemEventArgs e)
{
Console.WriteLine(e.Name + " " + e.ChangeType + " " + e.FullPath);
}
範例二、針對特定類型或特定檔案進行監控(監控C:\FileWatcher.txt是否有遭到更改)
若要監看所有檔案中的變更,請將 Filter 屬性設定為空字串 (""),或使用萬用字元 ("*.*")。若要監看指定的檔案,請設定 Filter 屬性為檔案名稱。例如,要監看 MyDoc.txt 檔案中的變更,請設定 Filter 屬性為 "MyDoc.txt"。您也可以監看某個類型檔案中的變更。例如,要監看文字檔中的變更,請設定 Filter 屬性為 "*.txt"。
using System.IO;
static void Main(string[] args)
{
FileSystemWatcher fsw = new FileSystemWatcher(@"C:\");
//不監控指定目錄內的子目錄,以免捕捉到太多系統運作的訊息,當然您也可以是個人情況而開啟。
fsw.IncludeSubdirectories = false;
//針對特定檔案進行監控(FileWatcher.txt),您可以是個人情況過濾監控資料,請看下面說明。
fsw.Filter = "FileWatcher.txt";
fsw.Changed += new FileSystemEventHandler(fsw_Changed);
fsw.EnableRaisingEvents = true;
Console.Read();
}
static void fsw_Changed(object sender, FileSystemEventArgs e)
{
Console.WriteLine(e.Name + " " + e.ChangeType + " "+ e.FullPath);
}
Filter 接受使用萬用字元來比對檔案
篩選條件字串 |
監看下列檔案 |
*.* |
所有檔案 (預設)。空字串 ("") 也會監看所有檔案。 |
*.txt |
所有副檔名為 "txt" 的檔案。 |
*recipe.doc |
所有以 "recipe" 為結尾且副檔名為 "doc" 的檔案。 |
win*.xml |
所有以 "win" 為開頭且副檔名為 "xml" 的檔案。 |
Sales*200?.xls |
符合下列項目:
但不符合:
|
MyReport.Doc |
只監看 MyReport.doc |
Windows 作業系統會在 FileSystemWatcher 所建立的緩衝區中,告知您的元件有檔案變更。如果在短時間內有很多的變更,緩衝區會溢位。這樣會造成元件失去追蹤目錄中變更的線索,而它將只會提供概括性的告知。使用 InternalBufferSize 屬性增加緩衝區大小會高度耗費資源,因為它來自不能交換到磁碟的未分頁記憶體,所以盡可能讓緩衝區愈小愈好,但是不至於小到會遺漏任何檔案變更事件。若要避免緩衝區溢位,使用 NotifyFilter 和 IncludeSubdirectories 屬性,您就可以篩選掉不想要的變更告知。
請注意,當遺漏事件或超過緩衝區大小時,由於與 Windows 作業系統的相依性,FileSystemWatcher 並不會引發 Error 事件。為了避免遺漏事件,請遵循下列方針:
-
使用 InternalBufferSize 屬性增加緩衝區大小,可以防止遺漏檔案系統變更事件。
-
避免監看具有長檔名的檔案,考慮使用較短名稱重新命名檔案。
-
盡可能讓事件處理程式碼越短越好
參考資料