c++如何利用C++17 filesystem::copy_file实现原子级文件备份【实战】

酷浩君_3060

酷浩君_3060

2026-03-30

332人浏览

原创

c++oding="utf-8" ?>

std::filesystem::copy_file 默认非原子,需配合临时文件与rename实现原子性;它不自动处理跨文件系统、权限继承、符号链接解引用等问题,且性能低于系统级拷贝工具。

c++如何利用c++17 filesystem::copy_file实现原子级文件备份【实战】

copy_file 默认不是原子的,必须显式指定 copy_options::skip_existing 或 copy_options::overwrite_existing

很多人以为 std::filesystem::copy_file 天然原子——其实它只是“单次调用完成复制”,但底层仍分三步:读源文件、写目标文件、设权限/时间戳。中间出错(如磁盘满、权限拒绝)会导致目标文件残留半成品。
真正能逼近原子语义的做法,是让目标路径始终指向一个完整副本,靠重命名切换。而 copy_file 本身不提供“先写临时再 rename”逻辑,得自己组合:
• 必须用 copy_options::overwrite_existing(否则遇到已存在文件直接抛 std::filesystem::filesystem_error)
• 目标路径不能是正在被其他进程读取的活跃文件(Windows 下会失败)
• 不支持跨文件系统移动;若源和目标在不同挂载点,copy_file 内部会退化为逐块拷贝,失败时无回滚

要实现真正原子备份,必须配合 std::filesystem::rename 和临时文件

核心思路是:复制到一个带随机后缀的临时路径(如 "backup.bak.tmp"),复制成功后再用 rename 原子替换原备份文件。这是 POSIX 和 Windows(NTFS)都保证原子的操作。
常见错误:
• 临时文件和目标文件放在不同目录(导致 rename 失败,报 EXDEV)
• 没检查 rename 返回值,误以为替换一定成功
• 临时文件名没加进程/时间戳,多进程并发时互相覆盖
实操建议:
• 临时路径和目标路径用同一父目录,例如:std::filesystem::path tmp = backup_path.parent_path() / ("." + backup_path.filename().string() + ".tmp")
• 复制前先 remove 旧临时文件(避免残留)
• copy_file 后立即 rename,中间不做任何可能崩溃的操作

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

Windows 下要注意 copy_options::skip_symlinks 和权限继承问题

Windows 的 NTFS 权限模型比 Unix 复杂,copy_file 默认不复制 ACL,只复制基本读写属性。如果你的备份需保留 DACL(比如服务账户依赖特定权限),必须手动调用 SetNamedSecurityInfo(Windows API),std::filesystem 不管这事。
另一个坑:
• 若源文件是符号链接(symlink),默认行为是复制链接本身(而非目标内容),容易误判为“空文件”
• 需显式传 copy_options::copy_symlinks 才解引用复制目标内容
• 但 Windows 上 symlink 创建需要管理员权限或开发者模式开启,普通用户环境可能根本建不出 symlink,所以实际中更常见的是 junction 或 hard link,而 filesystem 对 junction 不识别,会当普通目录处理

性能敏感场景下,copy_file 比 system("cp") 慢不少

实测在 Linux 上,copy_file 平均比 cp --reflink=auto 慢 2–5 倍,尤其对大文件(>1GB)。因为标准库实现通常用 read()/write() 循环,没用 sendfile 或 copy_file_range 系统调用。
如果你的备份场景强调速度且文件系统支持(XFS/Btrfs/ext4 with reflink),不如直接调用:
• system("cp --reflink=always -f source dest")(Linux)
• 或封装 CopyFileEx(Windows),它支持 COPY_FILE_NO_BUFFERING 和 COPY_FILE_RESTARTABLE
注意:
• copy_file 在 C++17 中不承诺使用零拷贝优化,各 STL 实现差异大(libstdc++ vs libc++)
• 即使开了 -O3,编译器也无法帮你在运行时选最优 syscall

真正的原子性不在 copy_file 函数里,而在你控制临时路径、rename 时机和错误清理的边界上。最容易被忽略的是:rename 成功后,旧备份文件的 inode 还在被某些进程 hold 着(比如 tail -f),这时候删它不会立刻释放磁盘空间——但那是备份策略问题,不是 copy_file 能解决的。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

6399

3

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.26

3239

3

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.07.27

2818

6

windows照片无法显示
windows照片无法显示

当我们尝试打开一张图片时,可能会出现一个错误提示,提示说"Windows照片查看器无法显示此图片,因为计算机上的可用内存不足",本专题为大家提供windows照片无法显示相关的文章,帮助大家解决该问题。

2023.08.01

1488

3

windows查看端口被占用的情况
windows查看端口被占用的情况

windows查看端口被占用的情况的方法:1、使用Windows自带的资源监视器;2、使用命令提示符查看端口信息;3、使用任务管理器查看占用端口的进程。本专题为大家提供windows查看端口被占用的情况的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2579

5

windows无法访问共享电脑
windows无法访问共享电脑

在现代社会中,共享电脑是办公室和家庭的重要组成部分。然而,有时我们可能会遇到Windows无法访问共享电脑的问题。这个问题可能会导致数据无法共享,影响工作和生活的正常进行。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.08

3290

4

windows自动更新
windows自动更新

Windows操作系统的自动更新功能可以确保系统及时获取最新的补丁和安全更新,以提高系统的稳定性和安全性。然而,有时候我们可能希望暂时或永久地关闭Windows的自动更新功能。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

1617

3

windows boot manager
windows boot manager

windows boot manager无法开机的解决方法:1、系统文件损坏,使用Windows安装光盘或USB启动盘进入恢复环境,选择修复计算机,然后选择自动修复;2、引导顺序错误,进入恢复环境,选择命令提示符,输入命令"bootrec /fixboot"和"bootrec /fixmbr",然后重新启动计算机;3、硬件问题,使用硬盘检测工具进行扫描和修复;4、重装操作系统。本专题还提供其他解决

2023.08.28

2497

4

windows锁屏快捷键
windows锁屏快捷键

windows锁屏快捷键是Windows键+L、Ctrl+Alt+Del、Windows键+D、Windows键+P和Windows键+R。本专题为大家提供windows相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.30

4887

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习