2009-05-06 3 views
29

La funzione API di Windows CopyFile ha un argomento BOOL bFailIfExists che consente di controllare se si desidera sovrascrivere o meno il file di destinazione, se esistente.come eseguire boost :: filesystem copy_file con sovrascrittura

La funzione boost::filesystemcopy_file non ha questo argomento e avrà esito negativo se il file di destinazione esiste. C'è un modo elegante per usare la funzione boost_file e sovrascrivere il file di destinazione? O è meglio semplicemente utilizzare l'API di Windows? La mia attuale piattaforma di destinazione è Windows, ma preferisco usare STL e aumentare dove possibile per mantenere la mia piattaforma di codice indipendente.

Grazie.

risposta

52

C'è un terzo enum argomento copy_file, boost :: filesystem :: :: copy_option overwrite_if_exists

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

Grazie anno. Non ero a conoscenza di questo. Sembra che questa opzione sia stata aggiunta a volte tra la versione 1.35 che stavo usando quando ho posto la domanda e la versione 1.41 che sto usando ora. Non riesco a trovare la modifica nella cronologia delle modifiche della libreria. Ma comunque, il problema è risolto. Non sono sicuro che ora dovrei accettare la tua risposta, forse ti chiederò su meta. –

+2

Attenzione: sembra esserci un problema con questo terzo argomento nell'implementazione POSIX. Vedi risposta di Vitaly. –

+2

@DanivanderMeer per il beneficio dei visitatori di questa pagina, [che bug è stato risolto anni fa] (https://svn.boost.org/trac/boost/ticket/4930). –

9

prova se il file di destinazione esiste prima e se lo fa poi rimuoverlo:

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

Oppure, se siete preoccupati per il file che appare tra la prova e la copia allora si potrebbe scrivere in un file temporaneo e quindi rinominarlo nel file di destinazione.

+0

Sì questo è possibile. Ma cosa succede se l'operazione di copia fallisce? Hai già cancellato il bersaglio. Non ha la stessa semantica della transazione di CopyFile. –

+0

L'alternativa al rinominare non ti dà questo? Ad ogni modo dall'osservazione della fonte di boost, l'API non consente di sovrascrivere facoltativamente il file. Potresti suggerire questo a loro come un miglioramento. Nel frattempo puoi prendere la tua copia della funzione boost_file e modificarla per prendere un extra parametro "sovrascrittura" bool. –

+0

Bene, immagino che la logica del rename funzionerà, ma speravo che ci fosse qualcosa nella libreria che risolve questo problema, e che non dovrò risolverlo da solo :). Proverò a suggerirlo come un miglioramento. Penso che questa sia una caratteristica logica e utile. Ad ogni modo, grazie per il tuo aiuto. Probabilmente userò CopyFile per ora. –

2

Esiste un modo elegante per utilizzare la funzione boost_file e sovrascrivere il file di destinazione?

Apparentemente non ci sono API dirette per farlo.

Oppure è meglio utilizzare semplicemente l'API di Windows? La mia attuale piattaforma di destinazione è Windows, ma preferisco usare STL e aumentare dove possibile per mantenere la mia piattaforma di codice indipendente.

Dalla documentazione:

Una proposta, N1975, per includere Boost.Filesystem nella relazione tecnica 2 è stato accettato dal comitato di C++ standard. La libreria Boost.Filesystem rimarrà in linea con la proposta del file system TR2 mentre attraversa il processo TR2. Si noti, tuttavia, che gli spazi dei nomi e la granularità dell'intestazione differiscono tra Boost.Filesystem e la proposta TR2.

Che suggerisce fortemente che attenersi a boost::filesystem è una buona idea.

17

Attenzione ai boost :: copy_file con copy_option :: overwrite_if_exists! Se il file di destinazione esiste ed è più piccolo dell'origine, la funzione sovrascriverà solo i primi byte di dimensione (from_file) nel file di destinazione.

Almeno per me questo era un avvertimento da quando ho presunti copy_option :: overwrite_if_exists colpisce file e non contenuti

+0

Ho provato a riprodurlo sulla mia piattaforma (Windows), ma non ci sono riuscito. la sovrascrittura influisce sul file completo, indipendentemente dalle dimensioni. Su quale piattaforma hai testato? –

+0

IFAIK copy_option :: overwrite_if_exists esiste solo su * nix (almeno in boost-1.44 per filesystem v2). Ma puoi facilmente vederlo nel codice sorgente, il file è aperto per la scrittura con O_WRONLY ma senza il flag O_TRUNC. –

+0

Sto usando boost 1.41. copy_option :: overwrite_if_exists esiste anche per Windows. copy_file chiama win32 API CopyFile (la versione A o W) con bFailIfExists in base all'opzione che si passa a boost :: copy_file. Quindi forse il comportamento per Windows e POSIX è diverso? –