std::filesystem::copy
来自cppreference.com
< cpp | filesystem
在标头 <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 起) |
void copy( const std::filesystem::path& from, const std::filesystem::path& to, |
(3) | (C++17 起) |
void copy( const std::filesystem::path& from, const std::filesystem::path& to, |
(4) | (C++17 起) |
复制文件与目录,带一些选项
1,2) 默认,等价于以
copy_options::none
为 options 调用 (3,4)。3,4) 复制文件或目录 from 到文件或目录 to,使用 options 所指定的复制选项。若 options 中存在 copy_options 任一选项组中多于一个的选项(即使在
copy_file
组中),则其行为未定义。行为如下:
- 首先,在做任何事前,以对下列之一者不多于一次的调用,获得 from 的类型与权限:
- 若 options 中给出
copy_options::skip_symlinks
、copy_options::copy_symlinks
或copy_options::create_symlinks
,则调用 std::filesystem::symlink_status; - 否则调用 std::filesystem::status。
- 若 options 中给出
- 若需要,则以对下列之一者不多于一次的调用,获取 to 的状态
- 若 options 中给出
copy_options::skip_symlinks
或copy_options::create_symlinks
,则调用 std::filesystem::symlink_status; - 否则调用 std::filesystem::status(包括 options 中给出
copy_options::copy_symlinks
的情况)。
- 若 options 中给出
- 若 from 或 to 拥有实现定义的文件类型,则此函数的效果是实现定义的。
- 若 from 不存在,则报告错误。
- 若 from 与 to 是如 std::filesystem::equivalent 所确定的同一文件,则报告错误。
- 若 from 或 to 不是常规文件、目录或符号链接,如 std::filesystem::is_other 所确定,则报告错误。
- 若 from 是目录,但 to 是常规文件,则报告错误。
- 若 from 是符号链接,则
- 若 options 中给出了
copy_options::skip_symlink
,则不做任何事。 - 否则,若 to 不存在且 options 中给出了
copy_options::copy_symlinks
,则表现如同 copy_symlink(from, to)。 - 否则,报告错误
- 若 options 中给出了
- 否则,若 from 是常规文件,则
- 若 options 中给出了
copy_options::directories_only
,则不做任何事。 - 否则,若 options 中给出了
copy_options::create_symlinks
,则创建到 to 的符号链接。注意:from 必须是绝对路径,除非 to 在当前目录中。 - 否则,若 options 中给出了
copy_options::create_hard_links
,则创建到 to 的硬链接。 - 否则,若 to 是目录,则表现如同 copy_file(from, to/from.filename(), options)(创建 from 的副本使其作为 to 目录中的文件)
- 否则,表现如同 copy_file(from, to, options)(复制文件)。
- 若 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 | - | 不抛出重载中报告错误的输出形参 |
返回值
(无)
异常
若内存分配失败,则任何不标记为 noexcept
的重载可能抛出 std::bad_alloc 。
1,3) 抛出 std::filesystem::filesystem_error,构造时以 from 为第一路径实参,以 to 为第二路径实参,并以OS 错误码为错误码实参。
若 OS API 调用失败,则 @2,4@ 设置 std::error_code& 形参
为 OS API 错误码,而未发生错误时则执行 ec.clear()。注解
复制目录时的默认行为是非递归复制:复制文件,但不复制子目录:
// 给定 // /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 <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"); // 复制文件 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++ 标准。
缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
---|---|---|---|
LWG 3013 | C++17 | error_code 重载被标记为 noexcept 但能分配内存
|
移除 noexcept |
LWG 2682 | C++17 | 试图为目录创建符号链接会成功但不做任何事 | 报告错误 |
参阅
(C++17) |
指定复制操作的语义 (枚举) |
(C++17) |
复制一个符号链接 (函数) |
(C++17) |
复制文件内容 (函数) |