备份前须检查文件占用:Windows下直接复制被占用文件会报错32,Linux虽可复制但内容可能不一致;建议以只读共享模式打开验证,关键文件需调用系统API检查句柄。

备份前必须检查文件是否被占用
Windows 下用 std::filesystem::copy 直接复制正在被其他进程写入的文件(比如 Excel 打开的 .xlsx、日志文件),大概率会抛出 std::filesystem::filesystem_error,错误码通常是 error_code 32(The process cannot access the file because it is being used by another process)。Linux 虽然允许复制,但可能读到不一致的内容。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 先尝试以只读 + 共享模式打开源文件:用
std::fstream构造时传入std::ios::in | std::ios::binary,若失败则跳过该文件或记录警告 - 对关键文件(如数据库文件)加额外判断:调用
GetFileInformationByHandle(Windows)或lsof检查句柄占用(Linux,需 shell 权限) - 不要依赖“文件修改时间没变就跳过”——有些程序会预分配并清空文件内容再写,mtime 不变但内容已不同
用 std::filesystem::copy 还是手动 std::ifstream/std::ofstream?
std::filesystem::copy 简洁,但默认行为在跨分区或权限受限时容易静默失败;手动流复制可控性强,适合需要校验、进度反馈或断点续传的场景。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 简单备份且目标路径同盘:优先用
std::filesystem::copy(src, dst, std::filesystem::copy_options::overwrite_existing) - 跨设备或需容错:改用分块读写,每次
read()最多 64KB,避免大文件 OOM;同时用std::hash_value或std::filesystem::file_size()校验源/目标大小是否一致 - 注意
std::filesystem::copy在 C++17 中不支持硬链接复制,若需保留硬链接语义,必须自己遍历 inode(Linux)或 reparse point(Windows)
如何避免备份过程中被用户误删或覆盖目标文件
直接往固定路径(如 "backup/latest.zip")写,一旦程序崩溃或磁盘满,旧备份就丢了。更糟的是,如果备份脚本被重复触发,多个实例可能并发写同一文件,导致内容损坏。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 目标文件名必须带时间戳:用
std::chrono::system_clock::now()生成唯一名,例如"backup_" + timestamp + ".zip",格式推荐YYYYMMDD_HHMMSS - 写入前先
std::filesystem::create_directories确保父目录存在,再用std::ofstream的std::ios::out | std::ios::binary | std::ios::trunc模式打开——trunc保证不会追加到旧文件末尾 - 写完后用
std::filesystem::rename原子替换(仅限同分区),比直接覆盖更安全;跨分区则先copy再remove源备份
定时触发该用 std::this_thread::sleep_for 还是系统级调度?
在主线程里死循环 + sleep_for 是最简方案,但进程退出时无法保证最后一次备份完成;用系统定时器(Windows Task Scheduler / Linux cron)更可靠,但要求备份逻辑可独立执行。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 命令行工具场景:把备份逻辑封装成无参数入口函数,编译为独立可执行文件,由 cron 或任务计划程序调用——避免 C++ 程序常驻内存带来的资源泄漏风险
- GUI 或服务进程内嵌:用
std::thread启动后台线程,每次 sleep 前检查std::atomic<bool> shutdown_requested</bool>,确保能响应退出信号 - 别用
time_t+localtime做“每天凌晨2点执行”的判断——时区切换或夏令时会导致偏移;改用std::chrono::floor<:chrono::days></:chrono::days>计算当日零点,再加偏移
真正麻烦的不是复制文件,而是判断“这个文件现在能不能安全读”,以及“上次备份到底成功没”。日志至少得记下每个文件的 size、mtime 和 copy 返回值,否则出问题时连排查方向都没有。


















