std::filesystem::copy
|   定义于头文件  <filesystem>
  | 
||
|   void copy( const std::filesystem::path& from,            const std::filesystem::path& to );  | 
(1) | (C++17 起) | 
|   void copy( const std::filesystem::path& from,            const std::filesystem::path& to,  | 
(2) | (C++17 起) | 
复制文件与目录,带一些选项
copy_options::none 为选项的 (2)from 到文件或目录 to ,使用 options 所指定的复制选项。若 options 中存在 copy_options 任一选项组中多于一个的选项(即使在无关乎 copy 的 copy_file 组中)行为如下:
-  首先,在做任何事前,以对下列之一者不多于一次的调用,获得 
from的类型与权限 
-  调用 std::filesystem::symlink_status ,若 
copy_options::skip_symlinks、copy_options::copy_symlinks或copy_options::create_symlinks存在于options; - 否则调用 std::filesystem::status 。
 
-  调用 std::filesystem::symlink_status ,若 
 
-  若需要,则以对下列之一者不多于一次的调用,获取 
to的状态 
-  若 
copy_options::skip_symlinks或copy_options::create_symlinks存在于options,则调用 std::filesystem::symlink_status ; -  否则调用 std::filesystem::status (包括 
copy_options::copy_symlinks存在于options的情况)。 
-  若 
 
-  若 
from或to拥有实现定义的文件类型,则此函数的效果是实现定义的。 -  若 
from不存在,则报告错误。 -  若 
from与to是如 std::filesystem::equivalent 所确定的同一文件,则报告错误 -  若 
from或to不是常规文件、目录或符号链接,如 std::filesystem::is_other 所确定,则报告错误 -  若 
from是目录,但to是常规文件,则报告错误 -  若 
from是符号链接,则 
-  若 
copy_options::skip_symlink存在于options,则不做任何事。 -  否则,若 
to不存在且copy_options::copy_symlinks存在于options,则表现如同 copy_symlink(from, to) - 否则,报告错误
 
-  若 
 
-  否则,若 
from是常规文件,则 
-  若 
copy_options::directories_only存在于options,则不做任何事 -  否则,若 
copy_options::create_symlinks存在于options,则创建到to的符号链接。注意:from必须是绝对路径,除非to在当前目录中。 -  否则,若 
copy_options::create_hard_links存在于options,则创建到to的硬链接 -  否则,若 
to是目录,则表现如同 copy_file(from, to/from.filename(), options) (创建from的副本,作为to目录中的文件) - 否则,表现如同 copy_file(from, to, options) (复制文件)
 
-  若 
 
-  否则,若 
from是目录而options中设置了copy_options::create_symlinks,则以等于 std::make_error_code(std::errc::is_a_directory) 的错误码报告错误。 -  否则,若 
from是目录且options拥有copy_options::recursive或是copy_options::none,则 
-  若 
to不存在,则首先执行 create_directory(to, from) (创建拥有旧目录属性副本的新目录) -  然后,不管 
to已存在还是刚被创建,在from所含有的文件上迭代,如同用 for (const std::filesystem::directory_entry& x : std::filesystem::directory_iterator(from)) ,并对于每个目录入口,递归地调用 copy(x.path(), to/x.path().filename(), options | in-recursive-copy) ,其中 in-recursive-copy 是于options设置时无其他效果的特殊位。(设置此位的独有目的是若options为copy_options::none则阻止递归复制子目录) 
-  若 
 
- 否则不做任何事。
 
参数
| from | - | 源文件、目录或符号链接的路径 | 
| to | - | 目标文件、目录或符号链接的路径 | 
| ec | - | 不抛出重载中报告错误的输出参数 | 
返回值
(无)
异常
不接受 std::error_code& 参数的重载在底层 OS API 错误时抛出 filesystem_error ,以第一 path 参数 from,第二 path 参数 to 和作为错误码参数的 OS 错误码构造。若 OS API 调用失败,则接受 std::error_code& 参数的重载设置该参数为 OS API 错误码,而若不出现错误则执行 ec.clear() 。若内存分配失败,则任何不标记为 noexcept 的重载可能抛出 std::bad_alloc 。
注解
复制目录时的默认行为是非递归复制:复制文件,但不复制子目录:
// 给定 // /dir1 含有 /dir1/file1 、 /dir1/file2 、 /dir1/dir2 // 而 /dir1/dir2 含有 /dir1/dir2/file3 std::filesystem::copy("/dir1", "/dir3"); // 之后 // 创建 /dir3 (拥有 /dir1 的属性) // /dir1/file1 被复制到 /dir3/file1 // /dir1/file2 被复制到 /dir3/file2
而带有 copy_options::recursive 时,亦复制子目录,递归地带有其内容。
// ……但在下一句后 std::filesystem::copy("/dir1", "/dir3", std::filesystem::copy_options::recursive); // 创建 /dir3 (拥有 /dir1 的属性) // /dir1/file1 被复制到 /dir3/file1 // /dir1/file2 被复制到 /dir3/file2 // 创建 /dir3/dir2 (拥有 /dir1/dir2 的属性) // /dir1/dir2/file3 被复制到 /dir3/dir2/file3
示例
#include <cstdlib> #include <iostream> #include <fstream> #include <filesystem> 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"); // 复制文件 fs::copy("sandbox/dir", "sandbox/dir2"); // 复制目录(非递归) 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"); }
可能的输出:
.
├── sandbox
│   ├── dir
│   │   └── subdir
│   ├── dir2
│   ├── file1.txt
│   └── file2.txt
└── sandbox_copy
    ├── dir
    │   └── subdir
    └── dir2
 
8 directories, 2 files缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
| DR | 应用于 | 出版时的行为 | 正确行为 | 
|---|---|---|---|
| LWG 3013 | C++17 |  error_code 重载被标记为 noexcept 但能分配内存
 | 
移除 noexcept | 
| LWG 2682 | C++17 | 试图为目录创建符号链接会成功但不做任何事 | 报告错误 | 
参阅
|    (C++17)  | 
  指定复制操作的语义  (枚举)  | 
|    (C++17)  | 
  复制一个符号链接  (函数)  | 
|    (C++17)  | 
  复制文件内容  (函数)  |