Question

Sous Windows, existe-t-il un moyen simple de savoir si un dossier contient un sous-fichier qui a changé ?

J'ai vérifié et la date de dernière modification sur le dossier n'est pas mise à jour lorsqu'un sous-fichier est modifié.

Existe-t-il une entrée de registre que je peux définir pour modifier ce comportement ?

Si cela est important, j'utilise un volume NTFS.

J'aimerais à terme avoir cette capacité à partir d'un programme C++.

L'analyse récursive d'un répertoire entier ne fonctionnera pas pour moi car le dossier est beaucoup trop volumineux.

Mise à jour:J'ai vraiment besoin d'un moyen de le faire sans qu'un processus ne soit en cours d'exécution pendant que le changement se produit.L'installation d'un observateur de système de fichiers n'est donc pas optimale pour moi.

Mise à jour2 :Le bit d'archive ne fonctionnera pas non plus car il présente le même problème que la date de dernière modification.Le bit d'archive du fichier sera défini, mais pas les dossiers.

Était-ce utile?

La solution

Ce article devrait aider.En gros, vous créez un ou plusieurs objets de notification tels que :

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()); 
   }

et puis vous attendez une notification :

 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;
      }
   }
}

Autres conseils

C'est peut-être exagéré, mais le Kit IFS de MS ou du FDDK d'OSR pourrait être une alternative.Créez votre propre pilote de filtre de système de fichiers avec une surveillance simple de toutes les modifications apportées au système de fichiers.

ReadDirectoryChangesW

Un excellent exemple de code dans cet article de CodeProject

Si vous ne pouvez pas exécuter un processus lorsque la modification se produit, vous ne pouvez pas faire grand-chose à part analyser le système de fichiers et vérifier la date/heure de modification.Cela nécessite cependant que vous stockiez la dernière date/heure de chaque fichier et que vous la compariez.

Vous pouvez accélérer cela en utilisant le bit d'archive (même si cela peut gâcher votre logiciel de sauvegarde, procédez donc avec précaution).

Un bit d'archive est un attribut de fichier présent dans de nombreux systèmes de fichiers informatiques, notamment FAT, FAT32 et NTFS.Le but d'un bit d'archives est de suivre les modifications incrémentielles dans les fichiers aux fins de la sauvegarde, également appelée archivage.

Comme le bit d'archive est un binaire binaire, il est soit 1 ou 0, ou dans ce cas plus fréquemment appelé set (1) et clair (0).Le système d'exploitation définit le bit d'archive chaque fois qu'un fichier est créé, déplacé, renommé ou autrement modifié de quelque manière que ce soit.Le bit des archives représente donc l'un des deux états:"changé" et "non changé" depuis la dernière sauvegarde.

Les bits des archives ne sont pas affectés en lisant simplement un fichier.Lorsqu'un fichier est copié, le bit d'archives du fichier d'origine n'est pas affecté, mais le bit d'archive de la copie sera défini au moment de la réalisation de la copie.

Le processus serait donc :

  1. Effacer le bit d'archive sur tous les fichiers
  2. Laissez le système de fichiers changer au fil du temps
  3. Analysez tous les fichiers - tous ceux avec le bit d'archive défini ont changé

Cela éliminera la nécessité pour votre programme de conserver son état, et comme vous parcourez uniquement les entrées du répertoire (où le bit est stocké) et qu'elles sont regroupées, cela devrait être très, très rapide.

Cependant, si vous pouvez exécuter un processus pendant les modifications, vous souhaiterez alors examiner le Observateur du système de fichiers classe.Voici un exemple de la façon dont vous pourriez l'utiliser.

Il existe également dans .FILET (pour les futurs chercheurs de ce type de problème)

Vous pouvez peut-être laisser un processus en cours d'exécution sur la machine pour surveiller les modifications et créer un fichier que vous pourrez lire plus tard.

-Adam

Peut-être pouvez-vous utiliser le journal des modifications NTFS 5 avec DeviceIoControl comme expliqué ici

Si vous n'êtes pas opposé à l'utilisation de .NET, le Observateur du système de fichiers la classe gérera cela pour vous assez facilement.

Dans le double post, quelqu'un a mentionné :Récepteur d'événements WMI

Je cherche toujours une meilleure réponse.

Rien de simple - si vous avez une application en cours d'exécution, vous pouvez utiliser les API de notification de modification de fichier Win32 (FindFirstChangeNotification) comme suggéré dans les autres réponses.avertissement:vers 2000, le scanner de virus en temps réel Trend Micro regroupait les modifications, ce qui rendait nécessaire l'utilisation de tampons très volumineux lors de la demande des listes de modifications du système de fichiers.

Si vous n'avez pas d'application en cours d'exécution, vous pouvez activer la journalisation NTFS et analyser le journal pour détecter les modifications. http://msdn.microsoft.com/en-us/library/aa363798(VS.85).aspx mais cela peut être plus lent que d'analyser l'intégralité du répertoire lorsque le nombre de modifications est supérieur au nombre de fichiers.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top