c# - filesystemwatcher vb.net ejemplo
Detectar archivos movidos usando FileSystemWatcher (5)
Me doy cuenta de que FileSystemWatcher no proporciona un evento Mover, en su lugar, generará eventos Eliminar y Crear separados para el mismo archivo. (FilesystemWatcher está observando las carpetas de origen y destino).
Sin embargo, ¿cómo diferenciamos entre un movimiento de archivo verdadero y alguna creación aleatoria de un archivo que tenga el mismo nombre que un archivo que se eliminó recientemente?
Algún tipo de propiedad de la clase FileSystemEventArgs como "AssociatedDeleteFile" a la que se asigna la ruta del archivo eliminado si es el resultado de un movimiento, o NULL de lo contrario, sería excelente. Pero por supuesto esto no existe.
También entiendo que FileSystemWatcher está operando en el nivel básico del sistema de archivos y, por lo tanto, el concepto de "Mover" solo puede ser significativo para las aplicaciones de nivel superior. Pero si este es el caso, ¿qué tipo de algoritmo recomendaría la gente para manejar esta situación en mi aplicación?
Actualización basada en comentarios:
La clase FileSystemWatcher parece ver mover un archivo simplemente como 2 eventos distintos, un Eliminar del archivo original, seguido de un Crear en la nueva ubicación.
Desafortunadamente, no hay un "enlace" entre estos eventos, por lo que no es obvio cómo diferenciar entre un movimiento de archivo y un Eliminar o Crear normal. En el nivel del sistema operativo, un movimiento se trata de manera especial, puede mover, digamos, un archivo de 1GB casi instantáneamente.
Un par de respuestas sugirieron utilizar un hash en los archivos para identificarlos de manera confiable entre los eventos, y probablemente tomaré este enfoque. Pero si alguien sabe cómo detectar un movimiento más simplemente, por favor, deje una respuesta.
Como ya mencionó, no hay una manera confiable de hacerlo con la clase predeterminada FileSystemWatcher proporcionada por C #. Puede aplicar ciertas heurísticas como nombre de archivo, hashes o identificadores de archivo únicos para asignar eventos creados y eliminados, pero ninguno de estos enfoques funcionará de manera confiable. Además, no puede obtener fácilmente el hash o el identificador de archivo para el archivo asociado con el evento eliminado, lo que significa que debe mantener estos valores en algún tipo de base de datos.
Creo que el único enfoque confiable para detectar movimientos de archivos es crear un observador del sistema de archivos propio. Por lo tanto, puede utilizar diferentes enfoques. Si solo va a ver los cambios en los sistemas de archivos NTFS, una solución podría ser leer el diario de cambios de NTFS como se describe here . Lo bueno de esto es que incluso te permite hacer un seguimiento de los cambios que ocurrieron mientras tu aplicación no se estaba ejecutando.
Otro enfoque es crear un controlador de minifiltros que rastree las operaciones del sistema de archivos y los reenvíe a su aplicación. Usando esto, básicamente obtiene toda la información sobre lo que está sucediendo con sus archivos y podrá obtener información sobre los archivos movidos. Un inconveniente de este enfoque es que debe crear un controlador independiente que deba instalarse en el sistema de destino. Lo bueno, sin embargo, es que no necesitarías comenzar desde cero, porque ya comencé a crear algo como esto: https://github.com/CenterDevice/MiniFSWatcher
Esto le permite simplemente rastrear archivos movidos como este:
var eventWatcher = new EventWatcher();
eventWatcher.OnRenameOrMove += (filename, oldFilename, process) =>
{
Console.WriteLine("File " + oldFilename + " has been moved to " + filename + " by process " + process );
};
eventWatcher.Connect();
eventWatcher.WatchPath("C://Users//MyUser//*");
Sin embargo, tenga en cuenta que esto requiere el código del kernel que debe firmarse para ejecutarse en la versión de 64 bits de Windows (si no disable comprobación de firmas para las pruebas). Al momento de escribir, este código también se encuentra en una etapa temprana de desarrollo, por lo que todavía no lo usaría en sistemas de producción. Pero incluso si no va a usar esto, debería darle cierta información sobre cómo se pueden rastrear los eventos del sistema de archivos en Windows.
Es posible que desee probar los eventos OnChanged y / o OnRenamed mencionados en docs .
Me atrevería a decir que un ''movimiento'' no existe, por lo que realmente tendrá que buscar un ''eliminar'' y luego marcar ese archivo como uno que podría ser ''posiblemente movido'', y luego, si ve un ''crear'' para él poco después, supongo que puedes asumir que estás en lo correcto.
¿Tiene un caso de creaciones de archivos aleatorios que afectan su detección de movimientos?
Según los docs :
Las operaciones comunes del sistema de archivos pueden provocar más de un evento. Por ejemplo, cuando un archivo se mueve de un directorio a otro, se pueden generar varios eventos OnChanged y algunos eventos OnCreated y OnDeleted. Mover un archivo es una operación compleja que consiste en múltiples operaciones simples, por lo tanto, genera múltiples eventos.
Entonces, si estás tratando de ser muy cuidadoso al detectar movimientos, y tener el mismo camino no es lo suficientemente bueno, tendrás que usar algún tipo de heurística. Por ejemplo, cree una "huella digital" con el nombre del archivo, el tamaño, la última hora de modificación, etc. para los archivos en la carpeta de origen. Cuando vea cualquier evento que pueda indicar un movimiento, verifique la "huella digital" contra el nuevo archivo.
Por lo que yo entiendo, el evento Renamed
es para los archivos que se mueven ...?
Mi error: los documentos específicamente dicen que solo los archivos dentro de una carpeta movida se consideran "renombrados" en una operación de cortar y pegar:
El sistema operativo y el objeto FileSystemWatcher interpretan una acción de cortar y pegar o una acción de movimiento como una acción de cambio de nombre de una carpeta y su contenido. Si corta y pega una carpeta con archivos en una carpeta que se está viendo, el objeto FileSystemWatcher informa solo de la carpeta como nueva, pero no de su contenido, ya que esencialmente solo tienen un nuevo nombre.
También dice acerca de mover archivos:
Las operaciones comunes del sistema de archivos pueden provocar más de un evento. Por ejemplo, cuando un archivo se mueve de un directorio a otro, se pueden generar varios eventos OnChanged y algunos eventos OnCreated y OnDeleted. Mover un archivo es una operación compleja que consiste en múltiples operaciones simples, por lo tanto, genera múltiples eventos.