2009-05-06 20 views
29

La función API de Windows CopyFile tiene un argumento BOOL bFailIfExists que le permite controlar si desea sobrescribir el archivo de destino, si existe.cómo realizar boost :: filesystem copy_file con sobrescribir

La función boost::filesystemcopy_file no tiene tal argumento, y fallará si el archivo de destino existe. ¿Existe alguna forma elegante de utilizar la función boost copy_file y sobrescribir el archivo de destino? ¿O es mejor simplemente usar la API de Windows? Mi plataforma objetivo actual es Windows, pero prefiero usar STL y potenciar, donde sea posible, para mantener mi plataforma de código independiente.

Gracias.

Respuesta

52

Hay un tercer argumento enumeración a copy_file, impulso :: sistema de archivos :: :: copy_option overwrite_if_exists

copy_file(source_path,destination_path,copy_option::overwrite_if_exists); 
+0

Gracias anno. No estaba enterado de esto. Parece que esta opción se agregó en algún momento entre la versión 1.35 que estaba usando cuando hice la pregunta y la versión 1.41 que estoy usando ahora. No puedo encontrar el cambio en el historial de cambios de la biblioteca. Pero de todos modos, problema resuelto. No estoy seguro si ahora debería aceptar su respuesta, tal vez pregunte en meta. –

+2

Cuidado: parece haber un problema con este tercer argumento en la implementación de POSIX. Ver respuesta de Vitaly. –

+2

@DanivanderMeer para el beneficio de los visitantes de esta página, [ese error se arregló hace años] (https://svn.boost.org/trac/boost/ticket/4930). –

9

prueba si el archivo de destino existe primero y si lo hace entonces eliminarlo:

if (exists (to_fp)) 
    remove (to_fp); 
copy_file (from_fp, to_fp); 

O si usted está preocupado acerca del archivo que aparece entre la prueba y la copia entonces usted podría escribir en un archivo temporal y luego cambiarle el nombre al archivo de destino.

+0

Si esto es posible. Pero, ¿qué sucede si la operación de copia falla? Ya borraste el objetivo. No tiene la misma semántica de transacción que CopyFile. –

+0

¿La alternativa de cambio de nombre no le da esto? De todos modos, al mirar la fuente de impulso, la API no le permite sobrescribir el archivo opcionalmente. Podrías sugerirles esto como una mejora. Mientras tanto, puede tomar su propia copia de la función boost copy_file y modificarla para tomar un parámetro de bool extra "overwrite". –

+0

Bueno, supongo que la lógica de cambio de nombre funcionará, pero esperaba que haya algo en la biblioteca que resuelva esto, y que no tendré que resolverlo yo mismo :). Trataré de sugerirlo como una mejora. Creo que esta es una característica lógica y útil. De todos modos, gracias por tu ayuda. Probablemente usaré CopyFile por ahora. –

2

¿Existe una manera elegante de utilizar la función boost copy_file y sobrescribir el archivo de destino?

Al parecer no hay ninguna API directa de hacerlo.

¿O es mejor simplemente usar la API de Windows? Mi plataforma objetivo actual es Windows, pero prefiero usar STL y potenciar, donde sea posible, para mantener mi plataforma de código independiente.

De la documentación:

Una propuesta, N1975, para incluir en el informe técnico Boost.Filesystem 2 ha sido aceptado por el Comité de Normas ++ C. La biblioteca Boost.Filesystem se mantendrá alineada con la propuesta del sistema de archivos TR2 a medida que avanza en el proceso TR2. Sin embargo, tenga en cuenta que los espacios de nombres y la granularidad del encabezado difieren entre Boost.Filesystem y la propuesta TR2.

Lo que sugiere fuertemente que la pervivencia de boost::filesystem es una buena idea.

17

Cuidado de impulso :: copy_file con copy_option :: overwrite_if_exists! Si el archivo de destino existe y es más pequeño que el origen, la función solo sobrescribirá los bytes de primer tamaño (desde archivo) en el archivo de destino.

Al menos para mí esto fue una advertencia desde que presuntos copy_option :: overwrite_if_exists afecta archivos y no contenido

+0

Intenté reproducir en mi plataforma (Windows), pero no pude. la sobrescritura afecta el archivo completo, independientemente del tamaño. ¿En qué plataforma has probado? –

+0

IFAIK copy_option :: overwrite_if_exists solo existe en * nix (al menos en boost-1.44 para el sistema de archivos v2). Pero puede verlo fácilmente en el código fuente, el archivo se abre para escribir con O_WRONLY pero sin el indicador O_TRUNC establecido. –

+0

Estoy usando boost 1.41. copy_option :: overwrite_if_exists existe también para Windows. copy_file llama a Win32 API CopyFile (la versión A o W) con bFailIfExists según la opción que pase para impulsar :: copy_file. ¿Entonces posiblemente el comportamiento para Windows y POSIX sea diferente? –

Cuestiones relacionadas