2010年12月26日 星期日

FileSystemWatcher and network device in C#

在C#中,對於檔案的監聽,提供了一個好用的API,即是FileSystemWatcher。他的語法也非常簡單,使用方法如下。

FileSystemWatcher watch = new FileSystemWatcher();
watch.Path = @"c:\";
watch.Changed += new FileSystemEventHandler(myFileWatchEvent);
watch.EnableRaisingEvents = true;

然後再寫一個myFileWatchEvent做目錄下檔案有變動時的對應事件。

private void AppFileWatchEvent(object sender, FileSystemEventArgs e) {
    FileInfo fi = new FileInfo(e.FullPath);
    if (fi.Name.CompareTo("test.txt") == 0) {
        //file change
    }
}

這樣一來,當目錄下的test.txt有任何更動時,就會觸發事件。

然而,FileSystemWatcher有個致命的缺點就是,他無法在網路磁碟機下正常運作。如果檔案在網路磁碟機下,由自己對檔案作改動,FileSystemWatcher是可以偵測到的。但如果是被其他人改動,除非我對該目錄手動作一個refresh動作,不然FileSystemWatcher是一點反應也沒有的。

這時候就要用老方法去監看檔案改變了。這裡是用定期看檔案日期有沒有做改變。

DateTime lastModifyTime = DateTime.MinValue;

private void DoFileChange(){
    FileInfo fw = new FileInfo(@"C:\test.txt");
    if (fw.Exists) {
        if(lastModifyTime == DateTime.MinValue){
            lastModifyTime = File.GetLastWriteTime(fw.FullName);
        }

        DateTime currentModifyTime = File.GetLastWriteTime(fw.FullName);

        if (lastModifyTime < currentModifyTime) {
            //File change   
        }
        lastModifyTime = currentModifyTime;
    }
}

然後用個while迴圈包起來。

private void DoFileChangeLoop(){
    while (true) {
        DoFileChange();
        Thread.Sleep(1000);
    }
}

當然,你必須將DoFileChangeLoop放在thread裡面。

實際執行下來,耗費的系統資源還蠻少的,在可以接受的範圍之內。

沒有留言: