Как узнать, изменился ли подфайл каталога

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

Я проверил, и дата последнего изменения в папке не обновляется при изменении подфайла.

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

Если это важно, я использую том NTFS.

В конечном итоге я бы хотел получить эту способность от программы на C++.

Рекурсивное сканирование всего каталога у меня не сработает, потому что папка слишком велика.

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

Обновление 2: бит архива также не будет работать, потому что он имеет ту же проблему, что и дата последнего изменения. Бит архива файла будет установлен, а папки - нет.

Хотя это не так просто, как перевернуть бит архива в самой папке, если Windows не поддерживает автоматическое «сворачивание» флага архива до уровня папки, чтение до тех пор, пока вы не найдете хотя бы один файл (или ни одного файла) с архивом. флаги могут быть вашим единственным вариантом, учитывая ваш минус выше

Troy DeMonbreun 11.09.2008 20:08

Можете ли вы сделать «Update3», объясняя, почему журнал NTFS не работает для вас?

Tony Lee 04.10.2008 00:41

Потому что я тоже хочу получить к нему доступ через сеть

Brian R. Bondy 04.10.2008 03:04

Ответ Сержа (stackoverflow.com/questions/56682/…) должен охватывать также сетевой случай.

tzot 06.10.2008 14:10
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
7
4
6 377
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

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

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

An archive bit is a file attribute present in many computer file systems, notably FAT, FAT32, and NTFS. The purpose of an archive bit is to track incremental changes to files for the purpose of backup, also called archiving.

As the archive bit is a binary bit, it is either 1 or 0, or in this case more frequently called set (1) and clear (0). The operating system sets the archive bit any time a file is created, moved, renamed, or otherwise modified in any way. The archive bit therefore represents one of two states: "changed" and "not changed" since the last backup.

Archive bits are not affected by simply reading a file. When a file is copied, the original file's archive bit is unaffected, however the copy's archive bit will be set at the time the copy is made.

Итак, процесс будет таким:

  1. Очистить бит архива для всех файлов
  2. Позвольте файловой системе меняться со временем
  3. Сканировать все файлы - все файлы с установленным битом архива изменились

Это избавит вашу программу от необходимости сохранять состояние, и, поскольку вы просматриваете только записи каталога (где хранится бит), и они сгруппированы, это должно быть очень, очень быстро.

Однако, если вы можете запустить процесс во время изменений, вам стоит взглянуть на класс FileSystemWatcher. Вот пример о том, как вы можете его использовать.

Он также существует в .СЕТЬ (для будущих искателей этого типа проблемы)

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

-Адам

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

reuben 26.12.2008 09:58

Если вы не против использования .NET, класс FileSystemWatcher справится с этим довольно легко.

Ничего простого - если у вас есть работающее приложение, вы можете использовать apis уведомления об изменении файла Win32 (FindFirstChangeNotification), как это предлагается с другими ответами. Предупреждение: микро-сканер вирусов в режиме реального времени тренд около 2000 года группирует изменения вместе, что приводит к необходимости использовать действительно большие буферы при запросе списков изменений файловой системы.

Если у вас нет работающего приложения, вы можете включить ведение журнала ntfs и сканировать журнал на предмет изменений http://msdn.microsoft.com/en-us/library/aa363798(VS.85).aspx, но это может быть медленнее, чем сканирование всего каталога, когда количество изменений больше, чем количество файлов.

Из двойного сообщения кто-то упомянул: приемник событий WMI

Тем не менее, все еще ищу ответ получше.

Ответ принят как подходящий

Этот статья должен помочь. По сути, вы создаете один или несколько объектов уведомления, например:

HANDLE dwChangeHandles[2]; 
dwChangeHandles[0] = FindFirstChangeNotification( 
      lpDir,                          // directory to watch 
      FALSE,                          // do not watch subtree 
      FILE_NOTIFY_CHANGE_FILE_NAME);  // watch file name changes 

   if (dwChangeHandles[0] == INVALID_HANDLE_VALUE) 
   {
     printf("\n ERROR: FindFirstChangeNotification function failed.\n");
     ExitProcess(GetLastError()); 
   }

// Watch the subtree for directory creation and deletion.  
   dwChangeHandles[1] = FindFirstChangeNotification( 
      lpDrive,                       // directory to watch 
      TRUE,                          // watch the subtree 
      FILE_NOTIFY_CHANGE_DIR_NAME);  // watch dir name changes 

   if (dwChangeHandles[1] == INVALID_HANDLE_VALUE) 
   {
     printf("\n ERROR: FindFirstChangeNotification function failed.\n");
     ExitProcess(GetLastError()); 
   }

а потом ждете уведомления:

 while (TRUE) 
   { 
   // Wait for notification. 
      printf("\nWaiting for notification...\n");

      DWORD dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles, 
         FALSE, INFINITE); 

      switch (dwWaitStatus) 
      { 
         case WAIT_OBJECT_0: 

         // A file was created, renamed, or deleted in the directory.
         // Restart the notification. 
             if ( FindNextChangeNotification(dwChangeHandles[0]) == FALSE )
             {
               printf("\n ERROR: FindNextChangeNotification function failed.\n");
               ExitProcess(GetLastError()); 
             }
             break; 

         case WAIT_OBJECT_0 + 1: 

         // Restart the notification. 
             if (FindNextChangeNotification(dwChangeHandles[1]) == FALSE )
             {
               printf("\n ERROR: FindNextChangeNotification function failed.\n");
               ExitProcess(GetLastError()); 
             }
             break; 

         case WAIT_TIMEOUT:

         // A time-out occurred. This would happen if some value other 
         // than INFINITE is used in the Wait call and no changes occur.
         // In a single-threaded environment, you might not want an
         // INFINITE wait.

            printf("\nNo changes in the time-out period.\n");
            break;

         default: 
            printf("\n ERROR: Unhandled dwWaitStatus.\n");
            ExitProcess(GetLastError());
            break;
      }
   }
}

Однако Брайан просил не об этом; этот ответ не дает решения для случая, когда какой-то файл (в папке) просто изменен (и не переименован, и ни один подкаталог / файл не создан или не удален).

tzot 06.10.2008 14:08

Это зависит от того, что вы понимаете под модифицированным. Если вы планируете поддерживать зеркало папки, то переименование обязательно, если есть модификация.

botismarius 23.01.2010 22:17

Возможно, вы можете использовать журнал изменений NTFS 5 с DeviceIoControl, как описано здесь

ReadDirectoryChangesW

Отличный пример кода в эта статья CodeProject

Серж, немного расшири свое предложение примером, применимым к вопросу.

tzot 06.10.2008 14:07

ΤΖΩΤΖΙΟΥ, я добавил ссылку на очень хорошую статью CP, которая содержит образец кода

Serge Wautier 10.10.2008 12:04

Возможно, это перебор, но альтернативой может быть Комплект IFS от MS или ФДДК от OSR. Создайте свой собственный драйвер фильтра файловой системы с простым отслеживанием всех изменений файловой системы.

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