std::filesystem::copy_file复制失败主因是默认不覆盖、不创建父目录、不解引用符号链接;需显式指定overwrite_existing、提前create_directories、Windows下注意只读属性。

std::filesystem::copy_file 复制失败时常见报错
直接调用 std::filesystem::copy_file(src, dst) 却没加选项,大概率遇到 std::filesystem::filesystem_error,错误信息通常是 "File exists" 或 "Permission denied"。这是因为默认行为是「不覆盖、不跳过、不创建父目录」——它连 dst 所在的文件夹都懒得检查是否存在。
- 目标路径不存在?会抛异常,不会自动创建上级目录
- 目标文件已存在?默认拒绝覆盖,除非显式传入
std::filesystem::copy_options::overwrite_existing - 源是符号链接?默认复制的是链接本身(而非目标),不是内容;要解引用得加
skip_symlinks配合copy_options::copy_symlinks
覆盖、跳过、递归?别乱组合 copy_options
std::filesystem::copy_options 是位掩码枚举,但不是所有组合都有意义。比如 overwrite_existing | skip_existing 逻辑冲突,编译器不报错,运行时行为未定义(实际多数实现忽略后者)。
- 想覆盖已有文件:只用
std::filesystem::copy_options::overwrite_existing - 想跳过已有文件:只用
std::filesystem::copy_options::skip_existing - 想保留时间戳(mtime/atime):加
std::filesystem::copy_options::copy_symlinks没用,得用std::filesystem::copy_options::preserve_attributes(注意:Windows 下仅部分属性可保留) - 别混用
recursive:这个选项只对std::filesystem::copy()有效,copy_file()专用于单文件,传了也无效
必须手动确保目标目录存在
std::filesystem::copy_file() 不处理路径中缺失的父目录。比如要把 "data/input.txt" 复制到 "backup/2024/data/input.txt",而 "backup/2024/data" 根本不存在,就会直接失败。
- 先调用
std::filesystem::create_directories(dst.parent_path())(推荐,会逐级创建) - 不要用
create_directory()—— 它只建一级,遇到"a/b/c"会失败 - 如果目标路径含相对路径(如
"../out/file.txt"),务必先用std::filesystem::absolute()归一化,否则parent_path()可能解析出错
Windows 下权限与只读文件的坑
在 Windows 上,若源文件被设为只读(FILE_ATTRIBUTE_READONLY),copy_file() 默认会把只读属性也复制过去。结果就是目标文件写保护,后续 overwrite_existing 会因权限不足失败。
立即学习“C++免费学习笔记(深入)”;
- 安全做法:复制前先用
std::filesystem::permissions(src, std::filesystem::perms::owner_write)临时加写权限(仅限源文件,不影响原始语义) - 或复制后立即修正目标文件权限:
std::filesystem::permissions(dst, std::filesystem::perms::owner_write) - Linux/macOS 一般不触发此问题,但若目标挂载为
noexec或ro,同样会报Permission denied
最易被忽略的是:copy_file() 不检查磁盘空间,也不提供进度回调。大文件复制中途失败,只能靠异常捕获 + 清理残留目标文件(因为部分写入可能已发生)。真要健壮,得自己封装一层带原子重命名和校验的逻辑。



















