2009-05-06 13 views
29

Die Windows-API-Funktion CopyFile hat ein Argument BOOL bFailIfExists, mit dem Sie steuern können, ob Sie die Zieldatei überschreiben möchten oder nicht, wenn sie existiert. Die boost::filesystemcopy_file-Funktion hat kein solches Argument und schlägt fehl, wenn die Zieldatei existiert. Gibt es eine elegante Möglichkeit, die Funktion boost copy_file zu verwenden und die Zieldatei zu überschreiben? Oder ist es besser, einfach die Windows-API zu verwenden? Meine aktuelle Zielplattform ist Windows, aber ich bevorzuge die Verwendung von STL und Boost, wo immer möglich, um meine Code-Plattform unabhängig zu halten.boost :: filesystem copy_file mit überschreiben

Vielen Dank.

Antwort

52

Es gibt ein drittes Enum Argument COPY_FILE, boost :: filesystem :: copy_option :: overwrite_if_exists

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

Danke anno. Ich war mir dessen nicht bewusst. Es scheint, dass diese Option irgendwann zwischen Version 1.35 hinzugefügt wurde, die ich verwendete, als ich die Frage stellte, und Version 1.41, die ich jetzt benutze. Ich kann die Änderung in der Änderungshistorie der Bibliothek nicht finden. Aber wie auch immer, Problem gelöst. Ich bin mir nicht sicher, ob ich deine Antwort jetzt akzeptieren sollte, vielleicht werde ich auf Meta fragen. –

+2

Vorsicht: Es scheint ein Problem mit diesem dritten Argument in der POSIX-Implementierung zu geben. Siehe Antwort von Vitaly. –

+2

@DanivanderMeer zum Vorteil der Besucher dieser Seite, [dieser Fehler wurde vor Jahren behoben] (https://svn.boost.org/trac/boost/ticket/4930). –

9

Testen Sie, ob die Zieldatei vorhanden ist zuerst und wenn es dann nicht entfernt:

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

Oder wenn Sie über die Datei zwischen dem Test und der Kopie erscheinen besorgt sind, dann könnten Sie in eine temporäre Datei schreiben und benenne es dann in die Zieldatei um.

+0

Ja dies möglich beeinträchtigt ist. Was aber, wenn der Kopiervorgang fehlschlägt? Sie haben das Ziel bereits gelöscht. Es hat nicht die gleiche transaktionsähnliche Semantik wie CopyFile. –

+0

Gibt dir die Umbenennungsalternative das nicht? Wie auch immer, wenn Sie sich die Boost-Quelle ansehen, erlaubt Ihnen die API nicht, die Datei optional zu überschreiben. Sie könnten dies als eine Verbesserung vorschlagen. In der Zwischenzeit können Sie Ihre eigene Kopie der Funktion boost copy_file erstellen und sie modifizieren, um einen zusätzlichen Bool-Parameter zu erhalten. –

+0

Nun, ich denke, die Umbenennungslogik wird funktionieren, aber ich hatte gehofft, dass da etwas in der Bibliothek ist, das das löst, und dass ich es nicht selbst lösen muss :). Ich werde versuchen, es als eine Verbesserung vorzuschlagen. Ich denke, das ist eine logische und hilfreiche Funktion. Wie auch immer, danke für deine Hilfe. Ich werde wahrscheinlich CopyFile für jetzt verwenden. –

2

Gibt es eine elegante Möglichkeit, die Funktion boost copy_file zu verwenden und die Zieldatei zu überschreiben?

Offenbar gibt es keine direkte API, um dies zu tun.

Oder ist es besser, einfach die Windows-API zu verwenden? Meine aktuelle Zielplattform ist Windows, aber ich bevorzuge die Verwendung von STL und Boost, wo immer möglich, um meine Code-Plattform unabhängig zu halten.

Aus der Dokumentation:

Ein Vorschlag, N1975, enthalten Boost.Filesystem in Technical Report 2 wurde von dem C++ Standards Committee akzeptiert. Die Boost.Filesystem-Bibliothek wird mit dem TR2-Dateisystem-Vorschlag ausgerichtet bleiben, während sie sich durch den TR2-Prozess hindurcharbeitet. Beachten Sie jedoch, dass sich die Namespaces und die Header-Granularität zwischen Boost.Filesystem und dem TR2-Vorschlag unterscheiden.

Was stark darauf hinweist, dass das Kleben mit boost::filesystem eine gute Idee ist.

17

Boost Vorsicht :: copy_file mit copy_option :: overwrite_if_exists! Wenn die Zieldatei existiert und kleiner als die Quelle ist, überschreibt die Funktion nur die Bytes der ersten Größe (from_file) in der Zieldatei.

Zumindest für mich war dies ein Nachteil, da ich copy_option vermutet :: overwrite_if_exists Dateien und nicht Inhalt

+0

Ich habe versucht, auf meiner Plattform (Windows) zu reproduzieren, konnte aber nicht. Das Überschreiben wirkt sich unabhängig von der Größe auf die gesamte Datei aus. Auf welcher Plattform haben Sie getestet? –

+0

IFAIK copy_option :: overwrite_if_exists existiert nur auf * nix (zumindest in boost-1.44 für Dateisystem v2). Aber Sie können es leicht im Quellcode sehen, die Datei ist zum Schreiben mit O_WRONLY geöffnet, aber ohne O_TRUNC Flag gesetzt. –

+0

Ich verwende Boost 1.41. copy_option :: overwrite_if_exists existiert auch für Windows. copy_file ruft win32 API CopyFile (die A- oder W-Version) mit bFailIfExists auf, entsprechend der Option, die Sie an boost :: copy_file übergeben. Also möglicherweise das Verhalten für Windows und POSIX ist anders? –

Verwandte Themen