C++17 标准首次正式引入了 std::filesystem,为文件和目录的操作提供了一套统一、类型安全且跨平台的 API。相较于传统的 POSIX 系统调用或 Windows API,std::filesystem 更易读、易用,并且充分利用了 C++ 的异常安全和类型检查机制。下面从几个典型场景出发,详细剖析 std::filesystem 的使用方法和最佳实践。
1. 目录遍历
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
int main() {
fs::path dir = "/usr/local/bin";
try {
for (const auto& entry : fs::recursive_directory_iterator(dir)) {
std::cout << (entry.is_directory() ? "[DIR] " : "[FILE] ") << entry.path() << '\n';
}
} catch (const fs::filesystem_error& e) {
std::cerr << "访问错误: " << e.what() << '\n';
}
}
- 递归 vs 非递归:
recursive_directory_iterator递归遍历子目录;若只需一次遍历,使用directory_iterator即可。 - 异常处理:任何 I/O 错误都抛出
std::filesystem_error,可通过code()获取std::error_code进一步判断。
2. 路径拼接与比较
fs::path p1 = "/var";
fs::path p2 = "log";
fs::path full = p1 / p2; // "/var/log"
if (fs::equivalent(full, "/var/log")) {
std::cout << "路径相等\n";
}
operator/:便捷地拼接路径,内部会自动处理分隔符。equivalent:不只比较字符串,还会考虑符号链接和大小写敏感性。
3. 读取和写入文件
#include <fstream>
fs::path file = "example.txt";
// 写入
std::ofstream ofs(file);
ofs << "Hello, std::filesystem!\n";
ofs.close();
// 读取
std::ifstream ifs(file);
std::string line;
while (std::getline(ifs, line)) {
std::cout << line << '\n';
}
ifs.close();
std::filesystem 并不直接提供文件内容操作,建议配合 `