2008-10-03 10 views
54

En los sistemas POSIX, el cambio de nombre (2) proporciona una operación de cambio de nombre atómico, incluida la sobrescritura del archivo de destino, si existe y si los permisos lo permiten.¿Es posible cambiar el nombre de un archivo atómico (con sobreescritura) en Windows?

¿Hay alguna forma de obtener la misma semántica en Windows? Sé acerca de MoveFileTransacted() en Vista y Server 2008, pero necesito esto para admitir Win2k y versiones posteriores.

La palabra clave aquí es atomic ... la solución no debe poder fallar de ninguna manera que deje la operación en un estado incoherente.

He visto a mucha gente decir que esto es imposible en win32, pero te pregunto, ¿de verdad?

Proporcione citas confiables si es posible.

+0

@ Adam Davis - Si usted tiene el control del programa del lector, así como el escritor, se puede resolver de esta manera. Reader hace io.Directory ("FileDone _ *. Dat") y elige el # más alto en lugar de *. Write crea un archivo con el nombre "FileWriting.dat" y lo renombra a "FileDone_002.dat" ..003, 004, etc. Esto no solo resuelve el problema de la eliminación/cambio de nombre no atómico, ese solo cambio de nombre es atómico. y, si el archivo anterior se mantiene abierto, aún es posible actualizarlo. Los lectores pueden mirar un nuevo archivo basado en un temporizador si no se vuelve a abrir con cada operación. Los lectores pueden limpiar archivos viejos. – FastAl

Respuesta

15

Win32 no garantiza las operaciones de metadatos de archivos atómicos. Proporcionaré una cita, pero no la hay; el hecho de que no haya una garantía escrita o documentada significa mucho.

Vas a tener que escribir tus propias rutinas para apoyar esto. Es desafortunado, pero no se puede esperar que win32 brinde este nivel de servicio, simplemente no fue diseñado para eso.

+4

Encuentro esto difícil de creer. Esto significaría que un corte de energía podría fácilmente dañar el sistema de archivos incluso si se trata de un sistema confiable como NTFS. – mafu

+1

@mafutrct Tenga en cuenta que la pregunta no es sobre la corrupción del sistema de archivos sino que se trata de asegurarse de que el cambio de nombre se complete con éxito o no ocurra. El sistema de archivos no se quedaría dañado, pero el nombre del archivo no se puede dejar ni en el estado original ni en el final. NTFS es un sistema de archivos de registro en diario, por lo que no (fácilmente) se dañará, pero dependiendo de la complejidad del cambio de nombre del archivo o el orden de las operaciones, es posible que no se deje en el estado final original o deseado. –

+4

Eso tiene sentido, pero también da mucho miedo. Para terminar con un nombre de archivo que no es ni original ni final, es casi una receta para el desastre. Especialmente desde (iirc) el estándar POSIX ya requiere operaciones de archivos metabólicos atómicos. – mafu

8

todavía tienen el() llamada de cambio de nombre en Windows, aunque me imagino que las garantías que desea no se puede hacer sin conocer el sistema de archivos que está utilizando - no hay garantías si está utilizando FAT, por ejemplo.

Sin embargo, puede usar MoveFileEx y usar las opciones MOVEFILE_REPLACE_EXISTING y MOVEFILE_WRITE_THROUGH. Este último tiene esta descripción en MSDN:

establecer este valor garantiza que un movimiento realizadas como copiar y borrar funcionamiento está volcado a disco antes de devuelve la función. La descarga ocurre al final de la operación de copia.

Sé que no es necesariamente lo mismo que una operación de cambio de nombre, pero creo que podría ser la mejor garantía que obtendría: si lo hace para un movimiento de archivo, debería ser un cambio de nombre más simple.

+5

Que yo sepa, si el destino existió y ocurre un error de E/S durante el paso de copia de datos, este destino "original" se pierde, por lo tanto, MoveFileEx no es atómico según sus requisitos. Es por eso que MoveFileTransacted se agregó más tarde. –

+3

MoveFileEx debería ser bueno. Tiene un indicador llamado MOVEFILE_COPY_ALLOWED que dice: "Si el archivo se va a mover a un volumen diferente, la función simula el movimiento utilizando las funciones CopyFile y DeleteFile". Entonces, no pases esta bandera y deberías tener algo que sea equivalente al cambio de nombre POSIX, ¿sí? – andrewrk

+0

El cambio de nombre falla si ya existe un nuevo archivo en Windows. Aparte de la atomicidad, la versión de Windows ni siquiera es semánticamente compatible con la versión de Unix. – wcochran

13

En Windows Vista y Windows Server 2008, una función de movimiento atómico se ha añadido - MoveFileTransacted()

Desafortunadamente esto no soluciona el problema con las versiones anteriores de Windows.

Interesting article here on MSDN.

+5

Oculto en los comentarios: esto ** no funcionará en recursos compartidos de red **. – sorin

+0

@sorin: la pregunta también pide un equivalente a una llamada POSIX que no sea atómica en los recursos compartidos de red. –

+0

Sin embargo, esta solución (y sus limitaciones para ciertas versiones de Windows) ya se mencionó en la pregunta, por lo que no es útil escribirla como respuesta. –

28
+4

Si lee http://msdn.microsoft.com/en-us/library/aa365512(VS.85).aspx, verá que 'ReplaceFile' es una operación de fusión complicada, sin indicación de que sea atómica. – Gabe

+14

El pasaje relevante de ese documento de investigación de MS: "En UNIX, rename() se garantiza que sobrescribe atómicamente la versión anterior del archivo. Debajo de Windows, la llamada a ReplaceFile() se usa atómicamente reemplaza un archivo por otro " –

+0

Encontré este comentario en algunos otros lugares en MSDN. Parece que ReplaceFile ahora es atómico a pesar de que no se menciona en la documentación directa pag. – Lothar

1

"El pasaje pertinente de ese trabajo de investigación MS: "Bajo ...."

Esto es lo que sugiere que la operación es atómica , pero es engañoso y solo adecuado para crear confusión. Lo que se requiere es eliminación atómica del archivo anterior y renombrar el nuevo archivo en un paso indivisible. Estas pueden ser dos operaciones de metadatos que en itse Si son atómicos, pero el compuesto NO es atómico.

+2

Esto es solo una decisión de implementación y fácil de implementar atómico o no. Lo que MS ha elegido hacer aún no está 100% despejado hasta que alguien con acceso al código fuente pueda informarnos. – Lothar

2

Un buen número de respuestas, pero no el que yo esperaba ... tuve la comprensión (tal vez erróneamente) que MoveFile podría ser atómica siempre que las estrellas alineadas adecuadas, se utilizaron banderas, y el sistema de archivos fue el lo mismo en la fuente como objetivo. De lo contrario, la operación volvería a un [Copiar-> Eliminar] Archivo.

Dado que; También entendí que MoveFile - cuando es atómico - simplemente estaba configurando la información del archivo que también se podía hacer aquí: setfileinfobyhandle.

esto no cubre el caso sustituir a pesar

Cuestiones relacionadas