2011-02-11 12 views
6

Bien, para comenzar esto es estrictamente para Windows y prefiero usar C++ sobre .NET pero no me opongo a boost::filesystem, aunque si se puede evitar en favor de la API de Windows directa, preferiría eso.¿Cómo determinar cuándo se realizan los archivos copiando para su posterior procesamiento?

Ahora el escenario es una aplicación en otra máquina que no puedo cambiar va a crear archivos en un directorio particular en la máquina que necesito para hacer copias de seguridad y hacer un procesamiento adicional. Actualmente he hecho una pequeña aplicación que se sentará y escuchará las notificaciones de cambio en un directorio de destino usando FindFirstChangeNotification y FindNextChangeNotification API de Windows.

El problema es que aunque puedo recibir notificaciones cuando se crean nuevos archivos en el directorio, modificaciones, cambios de tamaño, etc. solo se notifica una vez y no me dice específicamente qué archivos. También miré ReadDirectoryChangesW, pero es la misma historia, excepto que puedo obtener información un poco más específica.

Ahora puedo escanear el directorio e intentar adquirir bloqueos o abrir los archivos para determinar qué cambió específicamente desde la última notificación y si están disponibles para su uso posterior, pero en el caso de copiar un archivo grande he encontrado esto no es lo suficientemente bueno ya que el archivo no estará listo para ser manipulado y no recibiré ninguna otra notificación después del primero, así no habrá forma de saber cuándo se ha hecho realmente la copia, a menos que después de la primera notificación trate de adquirir continuamente se bloquea hasta que tenga éxito.

La única otra cosa que puedo pensar que sería menos hacker sería tener algún tipo de final del archivo testigo pero ya no tengo control sobre la aplicación de la creación de los archivos, en primer lugar yo no' Veo cómo haré eso y todavía no es ideal.

¿Alguna sugerencia?

+0

¿qué tal un programa de respaldo? –

Respuesta

4

Este es un problema bastante común y que no tiene una respuesta fácil. La adquisición de bloqueos es una de las mejores opciones cuando no puede cambiar la cosa en el extremo remoto. Otra cosa que he visto es mirar el archivo a intervalos hasta que el tamaño no cambie durante un intervalo o dos.

Otras estrategias incluyen escribir un archivo de no byte como activador cuando el archivo principal está completo y escribir en un directorio temporal y luego mover el archivo completo al destino real. Pero para ser confiable, debe ser el remitente quien lo controla. Como receptor, está obligado a mirar el directorio y esperar a que el archivo se establezca.

+0

Me jugué brevemente con la idea de un tiempo de espera con el crecimiento de archivos, pero parecía peor que las solicitudes de bloqueo. Tal vez soy ingenuamente optimista de que hay una solución que no involucra encuestas. – AJG85

+1

El problema es que el sistema operativo local no puede diferenciar entre un final de archivo exitoso y una copia abandonada o interrumpida, por lo que ni siquiera lo intenta.Incluso el método de sondeo de bloqueos no es infalible porque una copia interrumpida dará como resultado un bloqueo perdido y, cuando se reanude, el archivo ya podría haber sido respaldado. Como WMQ FTE es uno de los productos en los que me especializo, lo veo mucho y en muchas plataformas. Resulta ser un problema no trivial. –

+0

Eso también es un excelente punto que ni siquiera pensé en esa posibilidad. – AJG85

2

Parece que ReadDirectoryChangesW va a ser su mejor opción. Para cada operación de copia de archivo, debe recibir FILE_ACTION_ADDED seguido de un montón de notificaciones FILE_ACTION_MODIFIED. En la última notificación FILE_ACTION_MODIFIED, el archivo ya no debería estar bloqueado por el proceso de copia. Por lo tanto, si intenta adquirir un bloqueo después de cada FILE_ACTION_MODIFIED de la copia, debe fallar hasta que la copia se complete. No es una solución particularmente elegante, pero parece que no hay notificaciones disponibles para cuando se completa una copia de archivo.

+0

El problema parece ser el mecanismo de caché del sistema de archivos al menos en Windows 7 en mi prueba. Solo recibo un 'FILE_NOTIFY_CHANGE_LAST_WRITE' muy poco después del' FILE_NOTIFY_CHANGE_CREATION'. También parece crear el archivo de destino en el tamaño completo aunque la copia no esté completa, por lo que solo hay una descarga 'FILE_NOTIFY_CHANGE_SIZE' también. Es posible que necesite crear un hilo de trabajo para llamar a 'ReadDirectoryChangesW' para evitar perder notificaciones, pero con la duración de esta operación esperaría obtener más de una, incluso con la implementación actual. – AJG85

+0

@ AJG85 su observación es correcta, el primer tamaño de archivo se establece durante la copia (al menos por el explorador) a continuación, se escriben los datos. –

0

Puede procesar los datos una vez que el archivo está cerrado, ¿verdad? Entonces, la tarea es rastrear cuándo se cierra el archivo. Esto se puede hacer usando el controlador de filtro del sistema de archivos. Puede escribir el suyo o puede usar nuestro producto CallbackFilter.

+0

¿Tiene un enlace de referencia con más información sobre el controlador de filtro del sistema de archivos para que pueda determinar si vale la pena implementarlo? Esto suena como la interceptación de las partes internas del sistema y, por lo tanto, más allá del alcance del esfuerzo por las limitaciones de tiempo de este proyecto. – AJG85

+0

AJG85 de hecho, si desea implementar su propio filtro, tomaría meses de trabajo. Aquí hay información sobre filtros: http://www.microsoft.com/whdc/driver/filterdrv/default.mspx –

Cuestiones relacionadas