Как установить фильтр для 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*";
оба не работают. Это только основы, но я скучаю по нему. Спасибо..
5 ответов
есть решение.
идея состоит в том, чтобы следить за всеми расширениями, а затем в событии 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.");
}
}
вы не можете этого сделать. The Filter
свойство поддерживает только один фильтр одновременно. От документация:
использование нескольких фильтров, таких как
*.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 в наших интересах. :)
Edited-добавлена проверка null, чтобы избежать возможного исключения NullReferenceException.
быстрый взгляд в отражателе показывает, что фильтрация выполняется в коде .Net после того, как api windows сообщил об изменении файловой системы.
поэтому я бы предположил, что подход регистрации нескольких наблюдателей неэффективен, поскольку вы загружаете больше нагрузки на API, вызывая несколько обратных вызовов, и только один из фильтров будет соответствовать. Гораздо лучше просто зарегистрировать одного наблюдателя и отфильтровать результаты самостоятельно.
вы также можете фильтровать с помощью 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
}
}