std::filesystem::copy
Defined in header <filesystem>
|
||
void copy(
const
std::filesystem::path
& from,
const std::filesystem::path & to ) ; |
(1) | (since C++17) |
void copy(
const
std::filesystem::path
& from,
const std::filesystem::path& to, |
(2) | (since C++17) |
void copy(
const
std::filesystem::path
& from,
const std::filesystem::path& to, |
(3) | (since C++17) |
void copy(
const
std::filesystem::path
& from,
const
std::filesystem::path
& to, |
(4) | (since C++17) |
Copies files and directories, with a variety of options.
copy_options::none
used as options.copy_file
The behavior is as follows:
- First, before doing anything else, obtains type and permissions of from by no more than a single call to
-
-
std::filesystem::symlink_status, if
copy_options::skip_symlinks
,copy_options::copy_symlinks
, orcopy_options::create_symlinks
is present in options - std::filesystem::status otherwise.
-
std::filesystem::symlink_status, if
- If necessary, obtains the status of to, by no more than a single call to
-
-
std::filesystem::symlink_status, if
copy_options::skip_symlinks
orcopy_options::create_symlinks
is present in options -
std::filesystem::status otherwise (including the case where
copy_options::copy_symlinks
is present in options
-
std::filesystem::symlink_status, if
- If either from or to has an implementation-defined file type
- If from does not exist, reports an error.
- If from and to are the same file as determined by std::filesystem::equivalent
- If either from or to is not a regular file, a directory, or a symlink, as determined by std::filesystem::is_other
- If from is a directory, but to is a regular file, reports an error.
- If from is a symbolic link, then
-
- If
copy_options::skip_symlink
is present in options, does nothing. - Otherwise, if to does not exist and
copy_options::copy_symlinks
is present in options, then behaves as if copy_symlink(from, to) - Otherwise, reports an error.
- If
- Otherwise, if from is a regular file, then
-
- If
copy_options::directories_only
is present in options, does nothing. - Otherwise, if
copy_options::create_symlinks
is present in options, creates a symlink to to. Note: from must be an absolute path unless to - Otherwise, if
copy_options::create_hard_links
is present in options, creates a hard link to to - Otherwise, if to is a directory, then behaves as if copy_file(from, to/from.filename(), options) (creates a copy of from as a file in the directory to
- Otherwise, behaves as if copy_file(from, to, options) (copies the file).
- If
- Otherwise, if from is a directory and
copy_options::create_symlinks
is set in options, reports an error with an error code equal to std::make_error_code ( std::errc::is_a_directory ) - Otherwise, if from is a directory and either options has
copy_options::recursive
or iscopy_options::none
-
- If to does not exist, first executes create_directory(to, from)
- Then, whether to already existed or was just created, iterates over the files contained in from as if by
for
(
const
std::filesystem::directory_entry
& x :
std::filesystem::directory_iterator
(from)
)
and for each directory entry, recursively calls
copy(x.path
(
), to/x.path
(
).filename
(
), options | in-recursive-copy)
, where in-recursive-copy is a special bit that has no other effect when set in options. (The sole purpose of setting this bit is to prevent recursive copying subdirectories if options is
copy_options::none
- Otherwise does nothing.
Parameters
from | - | path to the source file, directory, or symlink |
to | - | path to the target file, directory, or symlink |
ec | - | out-parameter for error reporting in the non-throwing overload |
Return value
(none)
Exceptions
Any overload not marked noexcept
may throw std::bad_alloc if memory allocation fails.
Notes
The default behavior when copying directories is the non-recursive copy: the files are copied, but not the subdirectories:
// 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
While with copy_options::recursive
, the subdirectories are also copied, with their content, recursively.
// ...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
Example
#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"); }
Possible output:
. ├── sandbox │ ├── dir │ │ └── subdir │ ├── dir2 │ ├── file1.txt │ └── file2.txt └── sandbox_copy ├── dir │ └── subdir └── dir2 8 directories, 2 files
Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
LWG 3013 | C++17 | error_code overload marked noexcept but can allocate memory
|
noexcept removed |
LWG 2682 | C++17 | attempting to create a symlink for a directory succeeds but does nothing | reports an error |
See also
(C++17)
|
specifies semantics of copy operations (enum) |
(C++17)
|
copies a symbolic link (function) |
(C++17)
|
copies file contents (function) |