C++ std::filesystem复制文件时如何跳过被其他程序占用的文件?
C++ std::filesystem 目录复制跳过被占用文件的实现方案
原生std::filesystem::copy批量执行时遇到任何错误都会直接终止并抛出异常,没有原生跳过指定类型错误的参数,要实现跳过占用文件的逻辑,需要拆分批量复制流程,手动遍历目录+单文件错误捕获处理。
实现方案:手动遍历目录+错误码判断跳过占用文件
核心逻辑是用递归迭代器遍历源目录所有条目,对每个文件单独执行复制操作,通过std::error_code接收操作错误而非异常,判断错误类型为文件占用时直接跳过,继续处理后续文件。
Windows平台适配说明
你当前使用的是Windows路径,Windows下文件被占用时返回的系统错误码为:
- 32 (
ERROR_SHARING_VIOLATION):文件正在被其他进程占用,无法访问 - 33 (
ERROR_LOCK_VIOLATION):文件被其他进程加锁,无法访问
示例代码
#include <filesystem> #include <system_error> #include <iostream> #include <string> namespace fs = std::filesystem; void copy_dir_skip_locked(const fs::path& src_dir, const fs::path& dst_dir, fs::copy_options opts) { // 递归遍历源目录所有条目 for (const auto& entry : fs::recursive_directory_iterator(src_dir)) { // 构造对应目标路径 fs::path relative_path = fs::relative(entry.path(), src_dir); fs::path dst_path = dst_dir / relative_path; if (entry.is_directory()) { // 是目录则先创建目标目录,忽略已存在错误 std::error_code ec; fs::create_directories(dst_path, ec); if (ec) { std::cout << "创建目录失败,跳过:" << dst_path << " 错误:" << ec.message() << std::endl; } continue; } // 单文件复制,用error_code接收错误不抛出异常 std::error_code ec; fs::copy_file(entry.path(), dst_path, opts, ec); if (ec) { // 判断是否为文件占用错误,是则跳过,否则按需处理 if (ec.value() == 32 || ec.value() == 33) { std::cout << "文件被占用,跳过:" << entry.path() << std::endl; } else { std::cout << "复制失败,跳过:" << entry.path() << " 错误:" << ec.message() << std::endl; } } } } int main() { std::string user = "实际用户名"; fs::path src = "C:\\Users\\" + user + "\\AppData\\Local\\tee\\test\\User Data"; fs::path dst = "C:\\Users\\" + user + "\\AppData\\Local\\tee\\test\\Application"; auto copy_opts = fs::copy_options::overwrite_existing; copy_dir_skip_locked(src, dst, copy_opts); return 0; }
注意事项
- 若需要跨平台兼容,可对应补充Linux/macOS下文件占用的错误码判断,Linux下文件被强制加锁时通常返回
EAGAIN(11) - 可根据需求调整错误处理逻辑,比如仅跳过占用错误,其他错误直接终止程序
- 如果需要保留原文件的元信息(修改时间、权限等),可在复制成功后单独调用
std::filesystem::last_write_time等接口同步
内容的提问来源于stack exchange,提问作者Joel Emery
相关产品推荐
相关产品推荐

