提供されているサンプルでファイルシステム監視用のフィルターを設定するために使用されるこれらの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*";
両方とも機能しませんでした。これは基本的なことですが、見逃しています。ありがとう。
回避策があります。
すべての拡張機能を監視し、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.");
}
}
それはできません。 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);
}
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チェックを追加しました。
リフレクターを簡単に見ると、Windows APIがファイルシステムの変更を報告した後、.Netコードでフィルタリングが行われていることがわかります。
したがって、複数のウォッチャーを登録する方法は、APIにより多くの負荷をかけて複数のコールバックを引き起こし、フィルターの1つのみが一致するため、非効率的であることをお勧めします。単一のウォッチャーを登録し、結果を自分でフィルター処理する方がはるかに優れています。
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
}
}