2010-02-22 8 views
7

Tengo un programa que compara archivos en dos carpetas. Quiero detectar si se ha cambiado el nombre de un archivo, determinar el archivo más nuevo (más recientemente renombrado) y actualizar el nombre en el archivo anterior para que coincida.¿Cómo puedo determinar cuándo se renombró el archivo más recientemente?

Para lograr esto, verificaría si el archivo más nuevo es poco a poco idéntico al anterior, y si lo es, simplemente cambie el nombre del archivo anterior para que coincida con el nuevo.

El problema es que no tengo nada clave para decirme qué archivo se ha cambiado el nombre más recientemente.

Me encantaría una propiedad como FileInfo.LastModified, pero para los archivos que se han renombrado.

Ya he analizado soluciones como FileSystemWatcher, y eso no es realmente lo que estoy buscando. Me gustaría poder ejecutar mi sincronizador cuando lo desee, sin tener que preocuparme por algún proceso dedicado que rastree el estado de una carpeta.

¿Alguna idea?

Respuesta

1

A: Al menos en NTFS, puede adjuntar alternate data streams to a file. En su primera sincronización, puede adjuntar un GUID en un ADS a los archivos fuente para etiquetarlos.

B: Si no tiene acceso de escritura a la fuente, almacene hashes de los archivos que haya sincronizado en su repositorio de destino. Cuando la fuente cambia, solo tiene que actualizar los archivos fuente y solo comparar bit a bit si los hash colisionan. Dependiendo de la calidad y la velocidad de su función de hash, esto le ahorrará mucho tiempo.

+0

... y por supuesto, combínelo con 'LastModified'. –

+0

Ya guardo hashes de directorios en cada extremo. La coincidencia de datos bit por bit ya es posible. Solo esperaba poder ahorrar algo de ancho de banda al sincronizar en redes lentas moviendo archivos preexistentes. Parece que no hay una forma específica que no sea NTFS de hacer esto. –

+0

Esto podría funcionar sobre los controladores asignados (o recursos compartidos de red), siempre que el volumen fuente sea NTFS. Si aún no lo ha encontrado, puede ser de alguna ayuda: http://www.codeproject.com/KB/cs/ntfsstreams.aspx –

0

Puede crear un archivo de configuración que contenga una lista de todos los nombres esperados dentro de la carpeta y luego, si un archivo en la carpeta no es miembro de la lista esperada de nombres, determine que el archivo ha sido renombrado Sin embargo, esto agregaría otra capa de trabajo teniendo en cuenta que tendría que cambiar la lista cada vez que desee agregar un nuevo archivo a la carpeta.

+0

Eso realmente no funciona con mi herramienta. Está destinado a sincronizar dos directorios en ambas direcciones. –

+0

¿Has probado más allá de comparar? Es una gran herramienta para lo que estás buscando. – Aaron

0

Los sistemas de archivos generalmente no rastrean esto.

Dado que parece que está en Windows, puede usar GetFileInformationByHandle(). (Lo siento, no conozco el equivalente de C#). Puede usar los campos "índice de archivo" en la estructura devuelta para ver si los archivos tienen el mismo índice que algo que haya visto anteriormente. Tenga en cuenta que los enlaces duros también tendrán el mismo índice.

De forma alternativa, podría hash contenido de archivos de alguna manera.

No sé exactamente lo que estás tratando de hacer, así que no puedo decirte si alguno de estos puntos tiene sentido. Podría ser que la respuesta más razonable es "no, no puedes hacer eso".

+0

Estoy bastante seguro de que esto no es lo que el OP está buscando, pero es una idea interesante, sin embargo ... probablemente sea mejor que el plan de prueba del OP si los dos archivos son idénticos para determinar si se ha realizado un cambio de nombre. – rmeador

+0

Esa es una gran idea, pero hay muchos problemas con la identificación del archivo. La sección Comentarios dice: "El identificador que está almacenado en los miembros nFileIndexHigh y nFileIndexLow se llama ID de archivo. [Índice tan alto e índice bajo => ** ID de archivo **] Soporte para ** ID de archivo ** s es archivo específico del sistema [entonces, no todos los sistemas de archivos pueden soportarlo ... NTFS probablemente sí, ¿quién sabe si el resto lo hace?]. No se garantiza que las ID de los archivos sean únicas a lo largo del tiempo, porque los sistemas de archivos pueden reutilizarlas [pero para una instantánea del tiempo que serán, supongo]. En algunos casos, la identificación del archivo de un archivo puede cambiar con el tiempo ". – Alexandru

1

Si está ejecutando en una unidad NTFS puede habilitar el change journal que luego puede consultar para cosas como renombrar eventos. Sin embargo, debe ser un administrador para permitir que empiece y usará espacio en disco. Lamentablemente, no conozco ninguna implementación específica de C# para leer la revista.

0

Haría un CRC (por ejemplo CRC example) de (todos) los archivos en los 2 directorios que almacenan la última actualización con el valor CRC, nombre de archivo, etc. Después de eso, intente a través de las listas encontrando maches por el CRC y luego use los valores de fecha para decidir qué hacer.

+0

Ya lo hago. El problema es que el cambio de nombre de un archivo no modifica ninguna marca de tiempo. –

+0

Ah, hasta donde yo sé, no puede cambiar el nombre de un archivo y no modificarlo. Si pudieras, sería una llamada de API de muy bajo nivel (probablemente no expuesta por C#) –

Cuestiones relacionadas