Невозможно отслеживать документацию по словам с помощью FileSystemWatcher - PullRequest
4 голосов
/ 27 сентября 2011

У меня есть папка, содержащая документы из нескольких слов. Мне нужно отслеживать эту папку на наличие изменений в этих текстовых документах. Я сталкиваюсь со следующими проблемами:

  1. FileSystemWatcher никогда не сообщает точное имя изменяемого файла. Например, для файла abc.doc при первом сохранении сообщается, что «$ abc.doc был изменен».
  2. Для всех последующих сохранений в этот файл событие OnChanged в следующем коде не вызывается. Когда я изменил фильтр на watcher.Filter = "*.*", я обнаружил, что для последующих сохранений он сообщает «~ WRL0001.tmp is change».

Итак, суть в том, что я никогда не знаю, как изменилось точное имя файла.

Я использую следующий код

public static void Main()
{
    FileSystemWatcher watcher = new FileSystemWatcher();
    watcher.Path = @"C:\Users\Administrator\Documents\"; //"
    watcher.NotifyFilter = NotifyFilters.Size;
    watcher.Filter = "*.doc";
    watcher.Changed += new FileSystemEventHandler(OnChanged);

    watcher.EnableRaisingEvents = true;

    Console.WriteLine("Press \'q\' to quit the sample.");
    while (Console.Read() != 'q') ;
}

private static void OnChanged(object source, FileSystemEventArgs e)
{
    Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType);
}

Ответы [ 2 ]

3 голосов
/ 27 сентября 2011

Наблюдатель за файловой системой никогда не сообщает точное имя файла изменилось. Например, для файла abc.doc, он сообщает "~ $ abc.doc is изменено "при первом сохранении.

Причиной этого является то, что Word создает несколько временных файлов в текущем каталоге, в котором открыт исходный файл, и событие FileChanged вызывается также при создании нового файла. Фактически, FileSystemWatcher запускает FileCreated, за которым следует событие FileChanged. Поскольку вы не подписаны на FileCreated, вы видите только уведомление FileChanged.

Для всех последующих сохранений в этом файле событие OnChanged в следующий код не называется. Когда я изменил фильтр на watcher.Filter = ".", я обнаружил, что для последующих сохранений, он сообщает "~ WRL0001.tmp изменен".

То же, что и выше.

Но мне было любопытно узнать о вашей проблеме, и я немного изменил вашу программу и изменил ее следующим образом (разместив только соответствующие строки):

watcher.NotifyFilter =   NotifyFilters.Attributes;
watcher.Filter = "*.doc";
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.EnableRaisingEvents = true;

А потом я увидел фактическое имя изменяемого файла, напечатанное на консоли при сохранении файла. Когда я посмотрел, какие атрибуты изменились в исходном документе от одного сохранения к следующему, я заметил, что номер редакции увеличивается на 1 (я знаю, номер редакции не является атрибутом файла с точки зрения ОС). Я уверен, что другие атрибуты - из-за отсутствия лучшего слова - изменились. Это зависит от вас, если вы хотите установить NotificationFilter на NotifyFilters.Attributes;, чтобы сделать эту работу, но определенно странно, что это не сработает, например, с NotificationFilter =NotifyFilters.Size | NotifyFilters.LastWrite;.

enter image description here

0 голосов
/ 27 сентября 2011

Сохранение в произвольное имя файла обычно выполняется, чтобы сохранить атомарную операцию изменения файла и избежать уничтожения данных пользователя при сбоях записи.

Обычная последовательность:

  • Открыть файл "myfile.ext"
  • Редактировать
  • Записать файл изменений в" some_temp_name "в той же папке
  • Если запись прошла успешно, переименуйте" myfile.ext "в" myfile.old ", переименуйте" some_temp_name ""to" myfile.ext ".

В зависимости от программы последовательность может быть разной - т.е. последним переименованием может быть копирование файла или удаление оригинала.Вы должны следить за всеми типами изменений в папке назначения и наблюдать за окончательными обновлениями интересующих вас файлов (которые могут создавать уведомления вместо изменений).

...