So legen Sie einen Filter für FileSystemWatcher für mehrere Dateitypen fest

Überall finde ich diese beiden Codezeilen, die zum Einstellen des Filters für den Dateisystem-Watcher in den bereitgestellten Beispielen verwendet werden.

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

Ich möchte jedoch, dass mein Beobachter mehr Dateitypen überwacht, aber nicht alle. Wie kann ich das erreichen?

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

Ich habe diese probiert:

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

Beide haben nicht funktioniert. Dies ist nur Grundlagen, aber ich vermisse es. Vielen Dank..

Es gibt eine Problemumgehung.

Die Idee ist, auf alle Erweiterungen zu achten und dann im OnChange-Ereignis nach gewünschten Erweiterungen zu filtern:

 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."); } } 

Das kannst du nicht tun. Die Filter Eigenschaft unterstützt jeweils nur einen Filter. Aus der Dokumentation :

Die Verwendung mehrerer Filter wie *.txt|*.doc wird nicht unterstützt.

Sie müssen einen FileSystemWatcher für jeden Dateityp erstellen. Sie können sie dann alle an dieselbe Gruppe von FileSystemEventHandler binden:

 string[] filters = { "*.txt", "*.doc", "*.docx", "*.xls", "*.xlsx" }; List watchers = new List(); foreach(string f in filters) { FileSystemWatcher w = new FileSystemWatcher(); w.Filter = f; w.Changed += MyChangedHandler; watchers.Add(w); } 

Um die Lösung von Mrchief und jdhurst zu erweitern:

 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 } } 

Dadurch entfällt der Regex-Checker (was meiner Meinung nach zu viel Aufwand bedeutet) und nutzt Linq zu unserem Vorteil. 🙂

Editiert – Nullprüfung hinzugefügt, um mögliche NullReferenceException zu vermeiden.

Ein kurzer Blick in den Reflektor zeigt, dass die Filterung in .Net-Code erfolgt, nachdem die Windows-API die Änderung des Dateisystems gemeldet hat.

Ich würde daher vorschlagen, dass der Ansatz der Registrierung mehrerer Beobachter ineffizient ist, da Sie die API mehr belasten, was zu mehreren callbacken führt und nur einer der Filter übereinstimmt. Es ist viel besser, nur einen einzelnen Beobachter zu registrieren und die Ergebnisse selbst zu filtern.

Sie können auch filtern, indem Sie FileInfo mit dem String der gesuchten Erweiterung vergleichen.

Der Handler für ein Dateiänderungsereignis könnte beispielsweise so aussehen:

 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 } }