Как определить правильную модификацию файла?

В предыдущем вопросе один из моих вопросов состоял в том, как мое приложение могло узнать, что файл был переписан. Я должен был добавить: "другим приложением". Сначала я попробовал ShellNotify, какие отчеты об изменениях в каталоге, но не в определенном файле afaik, я что-то упустил?

Теперь я использую FileAge в таймере, который каждую секунду проверяет, изменился ли конкретный файл. Хотя это работает, он обнаруживает две модификации с интервалом около 13 мс; это поведение сохраняется, когда я изменяю интервал тестирования до 10 секунд. Код ниже является обратным вызовом таймера.

procedure TAMI_Column_Selector.doWork (Sender: TObject);
var new_stamp: TDateTime;
begin
   if FileAge (remove_extension (FileName) + '.csv', new_stamp) then
   begin
      if (new_stamp <> FDateTimeStamp) then
      begin
         FDateTimeStamp := new_stamp;
         FTask.SyncCall (notify_user);
      end; // if
   end; // if
end; // doWork //

Мои вопросы:

  1. Что именно вызывает notify_user быть вызванным дважды в коде выше? Дурацкая ошибка или какое-то странное поведение файловой системы (например, дата изменения устанавливается при открытии и закрытии файла)?
  2. Кажется "расточительным" проверять каждую секунду, изменился ли файл. Есть ли что-то вроде ShellNotify, которое уведомляет меня, только когда конкретный файл был изменен?

Обновить

Ответ Дэвида Хеффемана (использовать ReadDirectoryChangesW вместо опроса) является правильным ответом на вопрос 2. Однако это также приводит к нескольким вызовам во время одной модификации (с точки зрения пользователей), как упоминалось в вопросе 1.

Я сравнил ReadDirectoryChangesW и метод опроса. Протестировано с двумя файлами (0,5 МБ и 10 МБ). В обоих случаях метод опроса вызывался последовательно дважды и ReadDirectoryChangesW был вызван несколько раз (от 3 до 5 раз). Я вернусь к методу опроса и проигнорирую первый FileAge менять. Я знаю, что не могу быть уверен, что это поведение будет последовательным, поскольку я не понимаю механизм, вызывающий его.

1 ответ

Я знаю, что это не прямой ответ на ваш вопрос, но я бы порекомендовал использовать ReadDirectoryChangesW а не опрос.

Другие вопросы по тегам