Класса filesystemwatcher против избирательных, чтобы наблюдать за изменениями файла
Мне нужно настроить приложение, которое следит за файлами, создаваемыми в каталоге, как локально, так и на сетевом диске.
б FileSystemWatcher
или опрос по таймеру будет лучшим вариантом. Я использовал оба метода в прошлом, но не широко.
какие проблемы (производительность, надежность и т. д.) есть ли какой-либо метод?
13 ответов:
Я видел, что наблюдатель файловой системы не работает в производственных и тестовых средах. Я сейчас считаю это удобством, но не считаю его надежным. Мой шаблон состоял в том, чтобы следить за изменениями с помощью наблюдателя файловой системы, но иногда опрашивать, чтобы поймать отсутствующие изменения файлов.
Edit: если у вас есть пользовательский интерфейс, вы также можете дать пользователю возможность "обновить" изменения вместо опроса. Я бы объединил это с наблюдателем файловой системы.
самая большая проблема, с которой я столкнулся, - это отсутствие файлов, когда буфер заполняется. Легко исправить-просто увеличить буфер. Помните, что он содержит имена файлов и события, поэтому увеличьте его до ожидаемого количества файлов (проб и ошибок). Он использует память, которая не может быть выгружена, поэтому он может заставить другие процессы на страницу, если память становится низкой.
вот статья MSDN о буфере : FileSystemWatcher..::.InternalBufferSize Собственность
Per MSDN:
увеличение размера буфера дорого, так как он поступает из нестраничной памяти, которая не может быть заменена на диск, поэтому держите буфер как можно меньше. Чтобы избежать переполнения буфера, используйте свойства NotifyFilter и IncludeSubdirectories для фильтрации нежелательных уведомлений об изменениях.
мы используем 16 МБ из-за большой партии, ожидаемой в одно время. Отлично работает и никогда не пропускает файл.
мы также читаем все файлы перед началом процесс еще один...получите имена файлов, безопасно кэшированные (в нашем случае, в таблицу базы данных), а затем обработайте их.
для проблем блокировки файлов я создаю процесс, который ждет, пока файл будет разблокирован, ожидая одну секунду, затем две, затем четыре и т. д. Мы никогда. Это было в производстве без ошибок в течение двух лет.
на
FileSystemWatcher
может также пропустить изменения во время занятости, если количество изменений в очереди переполняет предоставленный буфер. Это не ограничение класса .NET как такового, а базовой инфраструктуры Win32. По нашему опыту, лучший способ минимизировать эту проблему-как можно быстрее удалить уведомления из очереди и разобраться с ними в другом потоке.Как упоминалось выше @ChillTemp, наблюдатель может не работать на общих ресурсах, отличных от Windows. Например, это не будет работа вообще на монтируемых приводах Novell.
Я согласен, что хороший компромисс-это сделать случайный опрос, чтобы забрать любые пропущенные изменения.
также обратите внимание, что наблюдатель файловой системы не является надежным на общих файловых ресурсах. Особенно если файл хранится на сервере Windows. FSW не должен использоваться ни для чего критического. Или следует использовать со случайным опросом, чтобы убедиться, что он ничего не пропустил.
лично я использовал
FileSystemWatcher
на рабочей системе, и она работала нормально. За последние 6 месяцев у него не было ни одной икоты, работающей 24x7. Он отслеживает одну локальную папку (которая является общей). У нас относительно небольшое количество файловых операций, которые придется обрабатывать (10 событий в сутки). Это не то, о чем мне когда-либо приходилось беспокоиться. Я бы использовал его снова, если бы мне пришлось переделать решение.
В настоящее время я использую
FileSystemWatcher
в XML-файл обновляется в среднем каждые 100 миллисекунд.Я нашел, что до тех пор, как
FileSystemWatcher
правильно настроен вы никогда не должны иметь проблем с местные файлы.у меня нет опыта в удаленном просмотре файлов и не-Windows shares.
Я бы счел опрос файла избыточным и не стоящим накладных расходов, если вы по своей сути не доверяете
FileSystemWatcher
или напрямую испытал ограничения, которые все остальные здесь перечислили (не Windows shares и удаленный просмотр файлов).
Я бы пошел с опросом.
сетевые проблемы вызывают
FileSystemWatcher
быть ненадежным (даже при перегрузке события ошибки).
У меня возникли проблемы с использованием
FileSystemWatcher
на сетевых ресурсах. Если вы находитесь в чистой среде Windows, это может быть не проблема, но я смотрел общий ресурс NFS, и поскольку NFS не имеет состояния, никогда не было уведомления, когда файл, который я смотрел, изменился.
У меня были некоторые большие проблемы с FSW на сетевых дисках: удаление файла всегда вызывало событие ошибки, а не удаленное событие. Я не нашел решения, поэтому теперь я избегаю FSW и использую опрос.
события создания, с другой стороны, работали нормально, поэтому, если вам нужно только следить за созданием файлов, вы можете пойти на FSW.
кроме того, у меня не было никаких проблем с локальными папками, независимо от того, разделяют или нет.
используя оба FSW и опрос является пустой тратой времени и ресурсов, на мой взгляд, и я удивлен, что опытные разработчики предлагают это. Если вам нужно использовать опрос для проверки любых "промахов FSW", то вы можете, естественно, полностью отказаться от FSW и использовать только опрос.
в настоящее время я пытаюсь решить, буду ли я использовать FSW или опрос для проекта, который я разрабатываю. Читая ответы, очевидно, что есть случаи, когда FSW покрывает потребности прекрасно, в то время как в других случаях, вы нужно опрос. К сожалению, нет ответа на самом деле имел дело с производительность разница (если есть), только с вопросами "надежности". Может кто-то ответить на эту часть вопроса?
EDIT : nmcleanточка для обоснованности использования как FSW, так и опроса(вы можете прочитать обсуждение в комментариях, если вам интересно) кажется очень рациональной объяснение, почему могут быть ситуации, которые используют как FSW, так и опрос и эффективным. Спасибо, что пролили свет на это для меня (и любого другого, имеющего такое же мнение),nmclean.
рабочее решение для работы с create event вместо change
даже для копирования, вырезать, вставить, переместить.
class Program { static void Main(string[] args) { string SourceFolderPath = "D:\SourcePath"; string DestinationFolderPath = "D:\DestinationPath"; FileSystemWatcher FileSystemWatcher = new FileSystemWatcher(); FileSystemWatcher.Path = SourceFolderPath; FileSystemWatcher.IncludeSubdirectories = false; FileSystemWatcher.NotifyFilter = NotifyFilters.FileName; // ON FILE NAME FILTER FileSystemWatcher.Filter = "*.txt"; FileSystemWatcher.Created +=FileSystemWatcher_Created; // TRIGGERED ONLY FOR FILE GOT CREATED BY COPY, CUT PASTE, MOVE FileSystemWatcher.EnableRaisingEvents = true; Console.Read(); } static void FileSystemWatcher_Created(object sender, FileSystemEventArgs e) { string SourceFolderPath = "D:\SourcePath"; string DestinationFolderPath = "D:\DestinationPath"; try { // DO SOMETING LIKE MOVE, COPY, ETC File.Copy(e.FullPath, DestinationFolderPath + @"\" + e.Name); } catch { } } }
решение для этого наблюдателя файлов при изменении атрибута файла с помощью статического хранилища
class Program { static string IsSameFile = string.Empty; // USE STATIC FOR TRACKING static void Main(string[] args) { string SourceFolderPath = "D:\SourcePath"; string DestinationFolderPath = "D:\DestinationPath"; FileSystemWatcher FileSystemWatcher = new FileSystemWatcher(); FileSystemWatcher.Path = SourceFolderPath; FileSystemWatcher.IncludeSubdirectories = false; FileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite; FileSystemWatcher.Filter = "*.txt"; FileSystemWatcher.Changed += FileSystemWatcher_Changed; FileSystemWatcher.EnableRaisingEvents = true; Console.Read(); } static void FileSystemWatcher_Changed(object sender, FileSystemEventArgs e) { if (e.Name == IsSameFile) //SKIPS ON MULTIPLE TRIGGERS { return; } else { string SourceFolderPath = "D:\SourcePath"; string DestinationFolderPath = "D:\DestinationPath"; try { // DO SOMETING LIKE MOVE, COPY, ETC File.Copy(e.FullPath, DestinationFolderPath + @"\" + e.Name); } catch { } } IsSameFile = e.Name; } }
это обходное решение для этой проблемы множественного события запуска.