std::filesystem 是 C++17 引入的标准库,用于跨平台地处理文件系统操作。下面将从基本概念、常用功能、路径组合与转换以及错误处理等方面,系统介绍如何在 C++ 中高效地使用 std::filesystem。
1. 基础概念
- path:表示文件系统路径的类。它内部存储为字符串,但提供了多种操作接口。
- directory_entry:包装一个路径及其对应的文件属性(如大小、时间戳等)。
- file_status:只包含文件状态信息,不包含文件内容。
2. 重要头文件与命名空间
#include <filesystem>
namespace fs = std::filesystem;
3. 常用功能
| 功能 | 示例 | 说明 |
|---|---|---|
| 路径拼接 | fs::path p = fs::current_path() / "data" / "file.txt"; |
使用 / 操作符拼接路径,自动处理分隔符。 |
| 检查文件/目录存在 | if (fs::exists(p)) { /* ... */ } |
判断路径是否存在。 |
| 创建目录 | fs::create_directories(p); |
创建多级目录。 |
| 删除文件/目录 | fs::remove(p); 或 fs::remove_all(p); |
删除单个文件或递归删除目录。 |
| 遍历目录 | for (auto const & entry : fs::directory_iterator(p)) { /* ... */ } |
逐个遍历目录下的文件/子目录。 |
| 获取文件属性 | auto sz = fs::file_size(p); |
获取文件大小。 |
| 复制/移动文件 | fs::copy(p, dest); 或 fs::rename(p, dest); |
复制或重命名文件。 |
4. 路径转换与标准化
- 绝对路径:
fs::absolute(p)。 - 相对路径:
fs::relative(p, base)。 - 标准化路径:
p = p.lexically_normal();去除.、..等。
5. 处理不同操作系统的分隔符
fs::path 自动根据平台使用正确的分隔符 (/ 或 \)。如果需要手动控制,可以使用 p.make_preferred() 把路径转换为平台默认形式。
6. 错误处理
许多文件系统操作会抛出 std::filesystem::filesystem_error。建议使用异常处理或检查返回值:
try {
fs::create_directory("test");
} catch (const fs::filesystem_error &e) {
std::cerr << e.what() << '\n';
}
或者使用 std::error_code:
std::error_code ec;
fs::create_directory("test", ec);
if (ec) {
std::cerr << ec.message() << '\n';
}
7. 性能注意事项
- 避免在循环中频繁创建
fs::path对象。可以在循环外创建一次并复用。 - 对于大量文件操作,使用
std::filesystem::directory_iterator的no_push选项(C++20)可减少栈帧占用。
8. 实战示例:复制指定后缀文件
#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
void copy_files_with_extension(const fs::path& src, const fs::path& dst, const std::string& ext) {
std::error_code ec;
fs::create_directories(dst, ec); // 确保目标目录存在
for (auto const & entry : fs::directory_iterator(src)) {
if (entry.path().extension() == ext) {
fs::copy(entry.path(), dst / entry.path().filename(), ec);
if (ec) {
std::cerr << "复制失败: " << entry.path() << " -> " << dst << " : " << ec.message() << '\n';
}
}
}
}
int main() {
copy_files_with_extension("src_dir", "dst_dir", ".txt");
return 0;
}
9. 小结
std::filesystem极大简化了跨平台文件系统操作。- 充分利用路径拼接、标准化、错误处理等特性,可写出简洁、健壮的文件管理代码。
- 在生产环境中,结合
std::error_code进行异常安全设计,既能获得异常信息,又能避免程序因未捕获异常而崩溃。
掌握上述基本用法后,你就能在 C++ 项目中灵活、可靠地处理文件与目录操作。