C++ filesystem怎么用 C++17文件系统库遍历与操作路径【库】

4次阅读

c++17 Filesystem 需手动链接 stdc++fs/lc++fs,且遍历目录须显式 try/catch 处理 filesystem_error,避免 range-for 因异常中断导致遗漏。

C++ filesystem怎么用 C++17文件系统库遍历与操作路径【库】

filesystem 在 C++17 中默认不可用,得手动开开关

不是写了 #include 就能用的。GCC 11+ 和 Clang 10+ 默认不链接 stdc++fs,MSVC 倒是内置支持,但 linux/macOS 下必加链接选项:-lstdc++fs(GCC)或 -lc++fs(Clang)。CMake 里得显式 link:target_link_libraries(my_target stdc++fs)。漏了会报类似 undefined reference to 'std::filesystem::directory_iterator::directory_iterator(std::filesystem::path const&)' 的链接错误。

遍历目录时别直接用 range-for,小心异常中断

std::filesystem::directory_iteratorrecursive_directory_iterator 都可能在访问某个路径时抛出 std::filesystem::filesystem_error(比如权限不足、路径被删、符号链接成环)。range-for 隐式调用 operator++,一旦抛异常就跳过后续——你根本不知道哪次迭代挂了。

稳妥做法是手动 try/catch:

for (auto iter = fs::directory_iterator("/tmp"); iter != fs::directory_iterator{}; ) {     try {         if (iter->is_regular_file()) {             std::cout << iter->path() << "n";         }         ++iter;     } catch (const fs::filesystem_error& e) {         std::cerr << "skipping " << iter->path() << ": " << e.what() << "n";         ++iter; // 别忘了推进,否则死循环     } }

path 拼接别用 +,优先用 /= 或 / 运算符

std::filesystem::path 重载了 /(返回新 path)和 /=(原地修改),语义清晰且自动处理分隔符:fs::path{"a"} / "b" / "c.txt"windows 和 Linux 下都生成正确路径。而用 +字符串拼接,会丢掉平台适配逻辑,还可能多出双反斜杠或缺分隔符。

立即学习C++免费学习笔记(深入)”;

常见误用场景:

  • 错:p = p + "/sub" → 可能在 Windows 上变成 "C:a/sub"
  • 对:p /= "sub"p = p / "sub"
  • 构造绝对路径时,用 fs::absolute(p) 而非手动拼 "./" + p.String()

exists() 和 is_regular_file() 不是原子操作,竞态条件得自己兜底

写类似 “如果文件存在就删它” 的逻辑时,if (exists(p)) remove(p); 是典型竞态:两次系统调用之间文件可能被删或改类型。C++17 没提供原子的 “remove_if_exists”,得靠 remove() 自身的返回值判断:

bool removed = fs::remove(p); // 返回 true 表示删成功了,false 表示不存在或无法删

同理,检查是否为普通文件后读取,中间也可能被改成目录或符号链接。真正健壮的代码得接受 filesystem_error 并按需处理,而不是依赖前置检查。

路径操作看似简单,但跨平台分隔符、权限异常、符号链接解析深度、时序竞态这四点,随便漏一个就在线上吐 core。

text=ZqhQzanResources