web-dev-qa-db-ja.com

複数のファイルタイプに対してFileSystemWatcherのフィルターを設定する方法は?

提供されているサンプルでファイルシステム監視用のフィルターを設定するために使用されるこれらの2行のコードはどこでも見つかります。

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*";

両方とも機能しませんでした。これは基本的なことですが、見逃しています。ありがとう。

60
nawfal

回避策があります。

すべての拡張機能を監視し、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."); 
    } 
} 
50
Mrchief

それはできません。 Filterプロパティは、一度に1つのフィルターのみをサポートします。 ドキュメント から:

*.txt|*.docなどの複数のフィルターの使用はサポートされていません。

ファイルタイプごとにFileSystemWatcherを作成する必要があります。その後、それらをすべてFileSystemEventHandlerの同じセットにバインドできます。

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);
}
80
Anders Abel

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の可能性を避けるためにnullチェックを追加しました。

17
Joe the Coder

リフレクターを簡単に見ると、Windows APIがファイルシステムの変更を報告した後、.Netコードでフィルタリングが行われていることがわかります。

したがって、複数のウォッチャーを登録する方法は、APIにより多くの負荷をかけて複数のコールバックを引き起こし、フィルターの1つのみが一致するため、非効率的であることをお勧めします。単一のウォッチャーを登録し、結果を自分でフィルター処理する方がはるかに優れています。

15
pbls624

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