Namensräume
Varianten
Aktionen

std::filesystem::copy

Von cppreference.com
 
 
 
Definiert in Header <filesystem>
void copy( const std::filesystem::path& from,
           const std::filesystem::path& to );
(1) (seit C++17)
void copy( const std::filesystem::path& from,

           const std::filesystem::path& to,

           std::error_code& ec );
(2) (seit C++17)
void copy( const std::filesystem::path& from,

           const std::filesystem::path& to,

           std::filesystem::copy_options options );
(3) (seit C++17)
void copy( const std::filesystem::path& from,

           const std::filesystem::path& to,
           std::filesystem::copy_options options,

           std::error_code& ec );
(4) (seit C++17)

Kopiert Dateien und Verzeichnisse mit einer Vielzahl von Optionen.

1,2) Der Standardwert, äquivalent zu (3,4) mit copy_options::none als options.
3,4) Kopiert die Datei oder das Verzeichnis from nach Datei oder Verzeichnis to, unter Verwendung der durch options angegebenen Kopieroptionen. Das Verhalten ist undefiniert, wenn mehr als eine Option in einer der copy_options-Optionsgruppen in options vorhanden ist (auch in der Gruppe copy_file).

Das Verhalten ist wie folgt:

  • Zuerst, bevor irgendetwas anderes geschieht, wird der Typ und die Berechtigungen von from durch nicht mehr als einen Aufruf von
  • Falls erforderlich, wird der Status von to durch nicht mehr als einen Aufruf von
  • Wenn entweder from oder to einen implementierungsdefinierten Dateityp hat, sind die Auswirkungen dieser Funktion implementierungsdefiniert.
  • Wenn from nicht existiert, wird ein Fehler gemeldet.
  • Wenn from und to dieselbe Datei sind, wie durch std::filesystem::equivalent bestimmt, wird ein Fehler gemeldet.
  • Wenn weder from noch to eine reguläre Datei, ein Verzeichnis oder ein Symlink ist, wie durch std::filesystem::is_other bestimmt, wird ein Fehler gemeldet.
  • Wenn from ein Verzeichnis ist, aber to eine reguläre Datei ist, wird ein Fehler gemeldet.
  • Wenn from ein symbolischer Link ist, dann
  • Wenn copy_options::skip_symlink in options vorhanden ist, tut dies nichts.
  • Andernfalls, wenn to nicht existiert und copy_options::copy_symlinks in options vorhanden ist, verhält es sich so, als wäre copy_symlink(from, to) aufgerufen worden.
  • Andernfalls wird ein Fehler gemeldet.
  • Andernfalls, wenn from eine reguläre Datei ist, dann
  • Wenn copy_options::directories_only in options vorhanden ist, tut dies nichts.
  • Andernfalls, wenn copy_options::create_symlinks in options vorhanden ist, wird ein Symlink zu to erstellt. Hinweis: from muss ein absoluter Pfad sein, es sei denn, to befindet sich im aktuellen Verzeichnis.
  • Andernfalls, wenn copy_options::create_hard_links in options vorhanden ist, wird ein Hardlink zu to erstellt.
  • Andernfalls, wenn to ein Verzeichnis ist, verhält es sich so, als wäre copy_file(from, to/from.filename(), options) aufgerufen worden (erstellt eine Kopie von from als Datei im Verzeichnis to).
  • Andernfalls verhält es sich so, als wäre copy_file(from, to, options) aufgerufen worden (kopiert die Datei).
  • Andernfalls, wenn from ein Verzeichnis ist und copy_options::create_symlinks in options gesetzt ist, wird ein Fehler mit einem Fehlercode gleich std::make_error_code(std::errc::is_a_directory) gemeldet.
  • Andernfalls, wenn from ein Verzeichnis ist und entweder options copy_options::recursive hat oder copy_options::none ist,
  • Wenn to nicht existiert, wird zuerst create_directory(to, from) ausgeführt (erstellt das neue Verzeichnis mit einer Kopie der Attribute des alten Verzeichnisses).
  • Dann, ob to bereits existierte oder gerade erstellt wurde, wird über die in from enthaltenen Dateien iteriert, als ob durch for (const std::filesystem::directory_entry& x : std::filesystem::directory_iterator(from)) und für jeden Verzeichniseintrag wird rekursiv copy(x.path(), to/x.path().filename(), options | in-recursive-copy) aufgerufen, wobei in-recursive-copy ein spezielles Bit ist, das keine andere Auswirkung hat, wenn es in options gesetzt ist. (Der einzige Zweck des Setzens dieses Bits ist es, das rekursive Kopieren von Unterverzeichnissen zu verhindern, wenn options copy_options::none ist.)
  • Andernfalls tut dies nichts.

Inhalt

[edit] Parameter

from - Pfad zur Quelldatei, zum Quellverzeichnis oder zum Quell-Symlink
to - Pfad zur Zieldatei, zum Zielverzeichnis oder zum Ziel-Symlink
ec - Ausgabeparameter für die Fehlerberichterstattung in der nicht auslösenden Überladung

[edit] Rückgabewert

(keine)

[edit] Ausnahmen

Jede Überladung, die nicht als noexcept markiert ist, kann std::bad_alloc auslösen, wenn die Speicherzuweisung fehlschlägt.

1,3) Löst std::filesystem::filesystem_error bei zugrundeliegenden Betriebssystem-API-Fehlern aus, konstruiert mit from als erstem Pfadargument, to als zweitem Pfadargument und dem Betriebssystem-Fehlercode als Fehlercodeargument.
2,4) Setzt einen std::error_code&-Parameter auf den OS-API-Fehlercode, wenn ein OS-API-Aufruf fehlschlägt, und führt ec.clear() aus, wenn keine Fehler auftreten.

[edit] Hinweise

Das Standardverhalten beim Kopieren von Verzeichnissen ist das nicht-rekursive Kopieren: Die Dateien werden kopiert, aber nicht die Unterverzeichnisse.

// Given
// /dir1 contains /dir1/file1, /dir1/file2, /dir1/dir2
// and /dir1/dir2 contains /dir1/dir2/file3
// After
std::filesystem::copy("/dir1", "/dir3");
// /dir3 is created (with the attributes of /dir1)
// /dir1/file1 is copied to /dir3/file1
// /dir1/file2 is copied to /dir3/file2

Während mit copy_options::recursive auch die Unterverzeichnisse mit ihrem Inhalt rekursiv kopiert werden.

// ...but after
std::filesystem::copy("/dir1", "/dir3", std::filesystem::copy_options::recursive);
// /dir3 is created (with the attributes of /dir1)
// /dir1/file1 is copied to /dir3/file1
// /dir1/file2 is copied to /dir3/file2
// /dir3/dir2 is created (with the attributes of /dir1/dir2)
// /dir1/dir2/file3 is copied to /dir3/dir2/file3

[edit] Beispiel

#include <cstdlib>
#include <filesystem>
#include <fstream>
#include <iostream>
namespace fs = std::filesystem;
 
int main()
{
    fs::create_directories("sandbox/dir/subdir");
    std::ofstream("sandbox/file1.txt").put('a');
    fs::copy("sandbox/file1.txt", "sandbox/file2.txt"); // copy file
    fs::copy("sandbox/dir", "sandbox/dir2"); // copy directory (non-recursive)
    const auto copyOptions = fs::copy_options::update_existing
                           | fs::copy_options::recursive
                           | fs::copy_options::directories_only
                           ;
    fs::copy("sandbox", "sandbox_copy", copyOptions); 
    static_cast<void>(std::system("tree"));
    fs::remove_all("sandbox");
    fs::remove_all("sandbox_copy");
}

Mögliche Ausgabe

.
├── sandbox
│   ├── dir
│   │   └── subdir
│   ├── dir2
│   ├── file1.txt
│   └── file2.txt
└── sandbox_copy
    ├── dir
    │   └── subdir
    └── dir2
 
8 directories, 2 files

[edit] Fehlerberichte

Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
LWG 3013 C++17 error_code-Überladung als noexcept markiert, kann aber Speicher allokieren noexcept entfernt
LWG 2682 C++17 Das Erstellen eines Symlinks für ein Verzeichnis gelingt, tut aber nichts meldet einen Fehler

[edit] Siehe auch

spezifiziert die Semantik von Kopiervorgängen
(Enum) [bearbeiten]
kopiert einen symbolischen Link
(Funktion) [bearbeiten]
(C++17)
kopiert Dateiinhalte
(Funktion) [bearbeiten]