2010-09-30 33 views
5

Tengo una utilidad que procesa un conjunto de archivos en un directorio; el proceso es relativamente lento (y hay muchos archivos) y así que he tratado de optimizar el proceso procesando solo los archivos que tienen una "última modificación" después de la última fecha de procesamiento.Windows: cómo determinar si un archivo ha sido modificado desde una fecha determinada

Normalmente esto funciona bien, sin embargo, he encontrado que copiar un archivo no cambia la fecha de la última modificación, por lo que hay varios escenarios que implican copiar archivos en los que el proceso omite ciertos archivos que han cambiado. ejemplo:

  1. El usuario procesa el directorio a las 9:00.
  2. Un archivo se copia desde este directorio y modificado para que tenga una fecha de última modificación de 9:30
  3. El directorio se procesa de nuevo a las 10:00
  4. El archivo modificado se copia de nuevo en el directorio a las 10:30
  5. Finalmente el directorio se procesa de nuevo a 11:00

a medida que la fecha de modificación del archivo dado es 09:30, y el directorio se procesó por última vez a las 10:00 el archivo es omitido cuando no debería ser

Desafortunadamente, lo anterior tiende a suceder con demasiada frecuencia en ciertas situaciones (como en un entorno colaborativo con control de fuente, etc.). Claramente mi lógica es defectuosa: lo que realmente necesito es una fecha de "última modificación o copia". ¿Existe tal cosa?

En su defecto, ¿hay otra manera de determinar rápidamente con una fiabilidad razonable si un archivo determinado ha cambiado?

Respuesta

4

¿Ha pensado en ejecutar las sumas de comprobación MD5 en los archivos y almacenarlos más adelante para comparar? Si siempre está procesando un determinado directorio, esto podría ser factible.

+0

Sí, sin embargo, esta es mi solución alternativa: espero que haya una forma de determinar si un archivo determinado ha cambiado (con una fiabilidad razonable) sin necesidad de leer el archivo. – Justin

9

Es posible que desee consultar utilizando la clase FileSystemWatcher. Esta clase le permite controlar cambios en un directorio y activará un evento cuando se modifique algo. Su código puede manejar el evento y procesar el archivo.

De 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); 
+0

El problema es que el proceso es un proceso por lotes, por lo que no se ejecutará todo el tiempo. De hecho, si la carpeta en cuestión es una unidad de red mapeada, es posible que la * computadora * ni siquiera se esté ejecutando. – Justin

+0

Sabía que escanear constantemente un directorio no era la mejor solución. ¡Gran respuesta! – Nolonar

0

¿Ha considerado la adición de un proceso de ver el directorio en su lugar? ¿Usando un FileSystemWatcher? Luego pasa de utilizar un proceso por lotes y un sistema en tiempo real para monitorear sus archivos.

3

Puede usar la clase FileInfo para obtener la información de cambio requerida (que posiblemente ya esté utilizando). Debe verificar dos propiedades de un archivo, que son LastWriteTime y CreationTime. Si alguno de ellos es más alto que su última fecha de procesamiento, debe copiar el archivo. Es un error común que CreationTime siempre es menor que LastWriteTime. No es. Si se copia un archivo a otro archivo, el archivo nuevo conserva el LastWriteTime de la fuente pero el CreationTime será el momento de la copia.

+1

¡Ah, tan cerca! Esto casi funciona, pero lamentablemente si está sobreescribiendo un archivo, parece que el tiempo de creación se deja como el momento en que se creó el archivo * original *. – Justin

+0

¿Qué método está utilizando para sobrescribir un archivo? Porque si se sobrescribe un archivo, su CreationTime será el mismo que antes pero su 'LastWriteTime' cambiará. Una de las propiedades TIENE que cambiar. – Yogesh

+0

Si utiliza "copiar" de cmd.exe, el archivo de destino 'LastWriteTime' se establece en el archivo de origen LWT, no se actualiza a la hora actual. – snemarch

0

Como habrás observado, copiar un archivo a un archivo de destino existente conserva el CreationTime del archivo existente y establece LastWriteTime en el LastWriteTime del archivo de origen, en lugar de la hora actual del sistema al hacer la copia.Dos posibles soluciones:

  1. Realice una eliminación y copia, asegurando que un destino CreationTime sea la hora actual del sistema.
  2. Compruebe el archivo A atributo rchived también y desactívelo durante el proceso. Al copiar source-> dest, se establecerá el atributo dest + A.
Cuestiones relacionadas