Windows: Как определить, был ли файл изменен с указанной даты - PullRequest
5 голосов
/ 30 сентября 2010

У меня есть утилита, которая обрабатывает набор файлов в каталоге - процесс относительно медленный (и файлов много), поэтому я попытался оптимизировать процесс, обрабатывая только те файлы, которые имеют «последнее изменение» позже, чем дата последней обработки.

Обычно это работает хорошо, однако я обнаружил, что копирование файла не меняет дату последнего изменения, и поэтому существуют различные сценарии, включающие копирование файлов, в которых определенные файлы, которые изменились, пропускаются процессом, например :

  1. Пользователь обрабатывает каталог в 9:00.
  2. Затем файл копируется из этого каталога и изменяется так, чтобы он имел дату последнего изменения 9: 30
  3. Затем каталог обрабатывается снова в 10:00
  4. Измененный файл затем копируется обратно в каталог в 10:30
  5. Наконец, каталог обрабатывается снова в 11:00

Поскольку дата изменения данного файла - 9:30, а каталог был последний раз обработан в 10:00, файл пропускается, когда его не должно быть.

К сожалению, вышеизложенное имеет тенденцию происходить слишком часто в определенных ситуациях (например, в среде совместной работы с контролем источников и т. Д.). Ясно, что моя логика ошибочна - мне действительно нужна дата «последнего изменения или копирования». такая вещь существует?

Если это не так, есть ли другой способ быстро и с достаточной достоверностью определить, изменился ли данный файл?

Ответы [ 5 ]

9 голосов
/ 30 сентября 2010

Возможно, вы захотите взглянуть на использование FileSystemWatcher класса.Этот класс позволяет вам отслеживать каталог на предмет изменений и запускать событие, когда что-то изменяется.Ваш код может затем обработать событие и обработать файл.

Из MSDN:

// Create a new FileSystemWatcher and set its properties.
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = args[1];
/* Watch for changes in LastAccess and LastWrite times, and
   the renaming of files or directories. */
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
   | NotifyFilters.FileName | NotifyFilters.DirectoryName;
// Only watch text files.
watcher.Filter = "*.txt";

// Add event handlers.
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);
4 голосов
/ 30 сентября 2010

Задумывались ли вы о запуске контрольных сумм MD5 для файлов и сохранении их позже для сравнения? Если вы всегда обрабатываете определенный каталог, это может быть осуществимо.

3 голосов
/ 30 сентября 2010

Вы можете использовать класс FileInfo, чтобы получить необходимую информацию об изменениях (которую вы, возможно, уже используете). Вам необходимо проверить два свойства файла: LastWriteTime и CreationTime. Если какой-либо из них превышает дату вашей последней обработки, вам необходимо скопировать файл. Это распространенное заблуждение, что CreationTime всегда меньше, чем LastWriteTime. Это не. Если файл копируется в другой файл, новый файл сохраняет LastWriteTime источника, но CreationTime будет временем копирования.

0 голосов
/ 30 сентября 2010

Как вы заметили, при копировании файла в существующий конечный файл сохраняется существующий файл CreationTime, и для LastWriteTime устанавливается значение LastWriteTime исходного файла, а не текущее системное время при выполнении копирования. Два возможных решения:

  1. Выполните удаление и копирование, убедившись, что целевое время CreationTime будет текущим временем системы.
  2. Проверьте атрибут файла A rchived и очистите его во время обработки. При копировании source-> dest, dest + будет установлен атрибут.
0 голосов
/ 30 сентября 2010

Рассматривали ли вы добавление процесса для просмотра каталога?Используя FileSystemWatcher?Затем вы переходите от использования пакетного процесса и системы реального времени для мониторинга ваших файлов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...