2011-08-06 60 views
48

我到處都找這兩行代碼用於設置在提供樣本文件系統觀察過濾器..如何爲多種文件類型設置FileSystemWatcher過濾器?

FileSystemWatcher watcher = new FileSystemWatcher(); 
watcher.Filter = "*.txt"; 
//or 
watcher.Filter = "*.*"; 

但我想我的守望者監控更多的文件類型,但不是全部。我怎樣才能做到這一點:

//watcher.Filter = "*.txt" | "*.doc" | "*.docx" | "*.xls" | "*.xlsx"; 

我嘗試這些:

watcher.Filter = "*.txt|*.doc|*.docx|*.xls|*.xlsx"; 
// and 
watcher.Filter = "*.txt;*.doc;*.docx;*.xls;*.xlsx*"; 

兩人都沒有工作。這只是基礎知識,但我很想念它。謝謝..

回答

35

有一種解決方法。

的想法是來監視所有擴展,然後在OnChange事件,篩選出所需的擴展:通過比較你的分機的字符串

FileSystemWatcher objWatcher = new FileSystemWatcher(); 
objWatcher.Filter = "*.*"; 
objWatcher.Changed += new FileSystemEventHandler(OnChanged); 

private static void OnChanged(object source, FileSystemEventArgs e) 
{ 
    // get the file's extension 
    string strFileExt = getFileExt(e.FullPath); 

    // filter file types 
    if (Regex.IsMatch(strFileExt, @"\.txt)|\.doc", RegexOptions.IgnoreCase)) 
    { 
     Console.WriteLine("watched file type changed."); 
    } 
} 
+1

很好的解決方法。你知道這是否會影響性能? –

+2

@Anders Abel:你的猜測和我一樣好!如果觀看的文件夾獲得大量文件更改,並且這些更改中的大部分都是針對_unwatched_文件類型的,那麼就會招致懲罰。否則,它不應該是那麼多的開銷。最後,你沒有別的辦法了,對吧? (除非去Win32 API) – Mrchief

+0

哈哈。 Mrchief,一個很酷的解決方法。我不確定我是否會爲此而努力。 @Anders Abel給出了另一種解決方法。現在我很困惑哪一個標記爲答案.. :) – nawfal

72

你不能那樣做。 Filter屬性一次只支持一個篩選器。從documentation

不支持使用多個過濾器,如*.txt|*.doc

您需要爲每種文件類型創建一個FileSystemWatcher。然後,您可以將它們全部綁定到同一組事件處理程序:

string[] filters = { "*.txt", "*.doc", "*.docx", "*.xls", "*.xlsx" }; 
List<FileSystemWatcher> watchers = new List<FileSystemWatcher>; 

foreach(string f in filters) 
{ 
    FileSystemWatcher w = new FileSystemWatcher(); 
    w.Filter = f; 
    w.Changed = MyChangedHandler; 
    watchers.Add(w); 
} 
+0

好的,謝謝你。自從微軟告訴我它不可能以後,我甚至不需要等待其他答案! :x :) – nawfal

+0

根據pbls624的回答,這比註冊'*。*'的效率低,並且手動執行過濾。 –

2

您還可以過濾用FileInfo尋找。

例如,對於文件更改事件處理程序可能看起來像:

void File_Changed(object sender, FileSystemEventArgs e) 
    { 
     FileInfo f = new FileInfo(e.FullPath); 

     if (f.Extension.Equals(".jpg") || f.Extension.Equals(".png")) 
     { 
      //Logic to do whatever it is you're trying to do goes here    
     } 
} 
+0

這就是Mrchief的回答本質上的問題。 – nawfal

16

要擴大Mrchief的和jdhurst的解決方案:

private string[] extensions = { ".css", ".less", ".cshtml", ".js" }; 
private void WatcherOnChanged(object sender, FileSystemEventArgs fileSystemEventArgs) 
{ 
    var ext = (Path.GetExtension(fileSystemEventArgs.FullPath) ?? string.Empty).ToLower(); 

    if (extensions.Any(ext.Equals)) 
    { 
     // Do your magic here 
    } 
} 

這消除了正則表達式檢查(這在我心目中是太多的開銷),並利用Linq的優勢。 :)

已編輯 - 添加空檢查以避免可能的NullReferenceException。

+1

爲什麼不使用「extensions.Contains(ext)」?簡單。甚至更好,「extensions.contains(ext,StringComparer.InvariantCultureIgnoreCase)」 – nawfal

9

快速查看反射器顯示在windows api報告文件系統更改後,以.Net代碼完成篩選。

因此,我建議註冊多個觀察者的方法是低效的,因爲您將更多的負載放在API上導致多個回調,並且只有一個過濾器匹配。更好地註冊一個觀察者並自己過濾結果。

+0

@vape我個人認爲這個答案增加了非常有價值的信息的問題。我可以證明他發現看到源代碼。 – nawfal