2008-09-11 21 views
7

En Windows, ¿hay una manera fácil de saber si una carpeta tiene un subarchivo que ha cambiado?Cómo ver si un subarchivo de un directorio ha cambiado

He verificado y la última fecha de modificación en la carpeta no se actualiza cuando cambia un subarchivo.

¿Existe una entrada de registro que pueda establecer que modifique este comportamiento?

Si es importante, estoy usando un volumen NTFS.

En última instancia, me gustaría tener esta habilidad de un programa C++.

Escanear un directorio completo recursivamente no funcionará para mí porque la carpeta es demasiado grande.

Actualización: Realmente necesito una forma de hacer esto sin un proceso en ejecución mientras ocurre el cambio. Entonces la instalación de un vigilante del sistema de archivos no es óptima para mí.

Update2: El bit de archivo tampoco funcionará porque tiene el mismo problema que la última fecha de modificación. Se establecerá el bit de archivo del archivo, pero las carpetas no.

+0

Aunque no es tan fácil como hacer que el bit de archivo se voltee en la carpeta, si Windows no admite la "carga" automática del indicador de archivo al nivel de carpeta, leyendo hasta encontrar al menos un archivo (o ningún archivo) con flags de archivo puede ser su única opción, dado su anterior con –

+0

¿Puede hacer una "Actualización3" que explique por qué el Diario NTFS no funciona para usted? –

+0

Porque también quiero acceder a él a través de la red –

Respuesta

6

Este article debería ayudar. Básicamente, se crea uno o más objeto de notificación, tales como:

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

y luego espera una notificación:

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

Sin embargo, esto no es lo que Brian solicitó; esta respuesta no proporciona una solución para el caso de que algún archivo (en la carpeta) simplemente se modifique (y no se renombre, y no se cree ni elimine ningún subdirector/archivo). – tzot

+0

Depende de lo que entiendas por modificado. Si planea mantener un espejo de una carpeta, cambie el nombre definitivamente si es una modificación. – botismarius

1

Si no puede ejecutar un proceso cuando ocurre el cambio, entonces no hay mucho que pueda hacer, excepto escanear el sistema de archivos y verificar la fecha/hora de la modificación. Sin embargo, esto requiere que almacene la última fecha/hora de cada archivo y compare.

Puede acelerar esto usando el archive bit (aunque puede estropear su software de copia de seguridad, por lo tanto, proceda con cuidado).

un bit de archivo es un atributo de archivo presente en muchos sistemas de archivos del ordenador, sobre todo FAT, FAT32 y NTFS. El propósito de de un bit de archivo es realizar un seguimiento de cambios incrementales en los archivos para el propósito de la copia de seguridad , también llamado archivo .

Como el bit de archivo es un bit binario, que es 1 o 0, o en este caso más frecuente llamado conjunto (1) y claro (0). El sistema operativo establece el bit de archivo en cualquier momento en que un archivo es creado, movido, renombrado o de otra manera modificado de alguna manera. Por lo tanto, el bit de archivo representa uno de los dos estados : "cambiado" y "no modificado" desde la última copia de seguridad.

Los bits de archivo no se ven afectados por simplemente leyendo un archivo. Cuando se copia un archivo , el bit del archivo original no se ve afectado, sin embargo, el bit de archivo de la copia se establecerá en el momento en que se realice la copia.

Así que el proceso sería:

  1. Borrar el bit de archivo de todos los archivos
  2. dejar que el cambio de sistema de archivos con el tiempo
  3. analizar todos los archivos - ninguna con el bit de archivo ha cambiado

Esto eliminará la necesidad de que su programa mantenga el estado, y ya que solo está revisando las entradas del directorio (donde el bit se almacena) y están agrupados, debería ser muy, muy rápido.

Si puede ejecutar un proceso durante los cambios, sin embargo, querrá consultar la clase FileSystemWatcher. Aquí hay un example de cómo puede usarlo.

También existe en .NET (para los futuros investigadores de este tipo de problema)

tal vez usted puede dejar un proceso que se ejecuta en la máquina de observar los cambios y la creación de un archivo para su lectura posterior.

-Adam

+1

Dependiendo de la naturaleza de su aplicación, no es necesariamente una buena idea cambiar los bits del archivo de los archivos que no es "suyo" ... – reuben

0

Nada fácil - si usted tiene una aplicación en ejecución puede utilizar las API de notificación de cambio de archivos Win32 (FindFirstChangeNotification) como se sugiere con las otras respuestas. advertencia: el escáner de virus micro en tiempo real de 2000 tendencias agruparía los cambios entre sí, por lo que es necesario utilizar almacenamientos intermedios realmente grandes al solicitar las listas de cambio del sistema de archivos.

Si no tiene una aplicación en ejecución, puede activar el diario ntfs y escanear el diario para cambios http://msdn.microsoft.com/en-us/library/aa363798(VS.85).aspx pero esto puede ser más lento que escanear todo el directorio cuando el número de cambios es mayor que el número de archivos.

0

Desde el doble post alguien mencionó: receptor de sucesos de WMI

Todavía estás buscando una mejor respuesta, aunque.

1

Tal vez se puede usar el NTFS 5 diario de cambios con DeviceIoControl como se explica here

2

ReadDirectoryChangesW

Algunos excelentes código de ejemplo en this CodeProject article

+0

Serge, expanda un poco su sugerencia con un ejemplo que se aplica a la pregunta. – tzot

+0

ΤΖΩΤΖΙΟΥ, agregué un enlace a un muy buen artículo de CP que contiene código de muestra –

3

Ésta es quizás una exageración, pero la IFS kit de la EM o la FDDK de OSR podría ser una alternativa. Cree su propio controlador de filtro del sistema de archivos con una simple supervisión de todos los cambios en el sistema de archivos.

Cuestiones relacionadas