c ++ - Sådan ser du om en underfil i en mappe er ændret

Indlæg af Hanne Mølgaard Plasc

Problem



I Windows er der en nem måde at fortælle om en mappe har en underfil, der er ændret?


Jeg bekræftede, og den sidste ændrede dato i mappen bliver ikke opdateret, når en underfil ændres.


Er der en registreringsdatabase, jeg kan indstille, der vil ændre denne adfærd?


Hvis det betyder noget, bruger jeg et NTFS-volumen.


Jeg vil i sidste ende gerne have denne evne fra et C ++-program.


Scanning af en hel mappe rekursivt virker ikke for mig, fordi mappen er for stor.


Opdatering: Jeg har virkelig brug for en måde at gøre dette på uden at en proces kører, mens ændringen sker. Så installation af et filsystem watcher er ikke optimalt for mig.


Update2: Arkivbiten fungerer heller ikke, fordi den har det samme problem som den sidste modifikationsdato. Filens arkivbit vil blive indstillet, men mapperne vil ikke.

Bedste reference


Denne artikel skal hjælpe. I grund og grund opretter du et eller flere meddelelsesobjekter som: [3]


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("
 ERROR: FindFirstChangeNotification function failed.
");
     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("
 ERROR: FindFirstChangeNotification function failed.
");
     ExitProcess(GetLastError()); 
   }


og så venter du på en anmeldelse:


 while (TRUE) 
   { 
   // Wait for notification. 
      printf("
Waiting for notification...
");

      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("
 ERROR: FindNextChangeNotification function failed.
");
               ExitProcess(GetLastError()); 
             }
             break; 

         case WAIT\_OBJECT\_0 + 1: 

         // Restart the notification. 
             if (FindNextChangeNotification(dwChangeHandles[1]) == FALSE )
             {
               printf("
 ERROR: FindNextChangeNotification function failed.
");
               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("
No changes in the time-out period.
");
            break;

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

Andre referencer 1


Dette er måske overkill, men IFS-kassen fra MS eller FDDK fra OSR kan være et alternativ. Opret din egen filsystemfilterdriver med simpel overvågning af alle ændringer i filsystemet. [4] [5]

Andre referencer 2


ReadDirectoryChangesW [6]


Nogle fremragende prøvekode i denne CodeProject artikel [7]

Andre referencer 3


Hvis du ikke kan køre en proces, når ændringen sker, så er der ikke meget du kan gøre, undtagen scan filsystemet, og tjek modifikationsdatoen/klokkeslættet. Dette kræver, at du gemmer hver fils sidste dato/tid og sammenligner.


Du kan fremskynde dette ved at bruge arkivet bit (selvom det kan ødelægge din backup software, så fortsæt omhyggeligt). [8]



  En arkivbit er en filattribut
  til stede i mange computer filsystemer,
  især FAT, FAT32 og NTFS. Det
  Formålet med en arkivbit er at spore
  trinvise ændringer i filer til
  Formålet med backup, også kaldet
  arkivering.

  
  Da arkivet bit er en binær bit, det
  er enten 1 eller 0, eller i dette tilfælde mere
  ofte kaldet sæt (1) og klart
  (0). Operativsystemet indstiller
  arkivbit, når som helst en fil er
  oprettet, flyttet, omdøbt eller ellers
  ændret på nogen måde. Arkivet bit
  repræsenterer derfor en af ​​to
  stater: 'ændret' og 'ikke ændret'
  siden den sidste backup.

  
  Arkivbiter påvirkes ikke af
  bare at læse en fil. Når en fil er
  kopieret, den oprindelige fils arkiv
  bit er upåvirket, men kopien 's
  arkivbit vil blive indstillet på det tidspunkt
  kopien er lavet



Så processen ville være:



  1. Ryd arkivet på alle filerne

  2. Lad filsystemet skifte over tid

  3. Scan alle filerne - alle med arkivbitsættet er ændret



Dette vil eliminere behovet for dit program for at holde tilstanden, og da du kun går over telefonbogsposterne (hvor biten er gemt) og de er grupperede, skal det være meget, meget hurtigt.


Hvis du kan køre en proces under ændringerne, så vil du se på FileSystemWatcher-klassen. Her er et eksempel på hvordan du kan bruge det. [9] [10]


Den findes også i .NET (for fremtidige brugere af denne type problem) [11]


Måske kan du lade en proces køre på maskinen og se efter ændringer og oprette en fil, så du kan læse senere.


-Adam

Andre referencer 4


Måske kan du bruge NTFS 5 Change Journal med DeviceIoControl som forklaret her [12]

Andre referencer 5


Hvis du ikke er imod at bruge .NET, vil FileSystemWatcher-klassen håndtere dette for dig ganske nemt. [13]

Andre referencer 6


Fra den dobbelte post nævner nogen: WMI Event Sink


Stadig på udkig efter et bedre svar dog.

Andre referencer 7


Intet nemt - hvis du har en kørende app, kan du bruge Win32 File Change Notification Apis (FindFirstChangeNotification) som foreslået med de andre svar. advarsel: circa 2000 trend micro real-time virus scanner ville gruppere ændringerne sammen, hvilket gør det nødvendigt at bruge rigtig store buffere, når de anmoder om ændring af filsystemet.


Hvis du ikke har en kørende app, kan du tænde for ntfs journaling og scanne journalen for ændringer http://msdn.microsoft.com/en-us/library/aa363798(VS.85).aspx, men det kan være langsommere end at scanne hele mappen, når # af ændringer er større end # af filer. [14]