
用 C++17 的 库操作文件和目录,核心是 std::filesystem::path 和各类自由函数(如 exists、create_directory、copy 等),所有功能都基于路径抽象,无需手动拼接字符串或调用系统 API。
构造和处理路径
std::filesystem::path 是路径的智能封装,自动处理分隔符(Windows 用 \,Linux/macOS 用 /),支持多种构造方式,还能拆解、拼接、规范化:
- 直接用字符串字面量构造:
fs::path p = "data/logs/app.log"; - 用
/操作符拼接(推荐):fs::path p = "data" / "logs" / "app.log"; - 获取父目录:
p.parent_path();获取文件名:p.filename();获取扩展名:p.extension() - 标准化路径(处理
..和.):p = p.lexically_normal();
判断与查询文件/目录状态
用 status() 或 symlink_status() 获取文件状态,再配合类型判断函数,避免竞态条件(即“检查后使用”不安全):
- 存在且是普通文件:
fs::is_regular_file(p) - 存在且是目录:
fs::is_directory(p) - 是否为符号链接:
fs::is_symlink(p) - 获取大小(仅对常规文件有效):
fs::file_size(p) - 获取最后修改时间:
fs::last_write_time(p)
注意:不要先调 exists() 再调 is_regular_file(),应直接用后者——它内部已包含存在性检查。
立即学习“C++免费学习笔记(深入)”;
创建、删除与移动文件/目录
所有操作都返回 bool 表示是否成功(失败通常因权限不足或路径无效),不抛异常(除非明确启用异常模式):
- 创建单层目录:
fs::create_directory("my_folder") - 递归创建多级目录:
fs::create_directories("a/b/c") - 删除空目录:
fs::remove("empty_dir") - 递归删除整个目录树:
fs::remove_all("project_build") - 重命名或移动(跨卷可能变为复制+删除):
fs::rename("old.txt", "new.txt") - 复制文件(不支持目录):
fs::copy_file("src.txt", "dst.txt", fs::copy_options::overwrite_existing)
遍历目录内容
用 fs::directory_iterator 遍历单层,用 fs::recursive_directory_iterator 深度遍历。迭代器解引用得到 fs::directory_entry,可直接调用状态相关方法:
- 遍历当前目录所有条目:
for (const auto& entry : fs::directory_iterator("src")) { ... } - 跳过符号链接指向的目标,只遍历链接本身:
fs::directory_iterator(p, fs::directory_options::skip_permission_denied) - 过滤出所有 .cpp 文件:
if (entry.path().extension() == ".cpp") { ... } - 获取每个条目的文件大小:
entry.file_size()(比反复调fs::file_size(entry.path())更高效)
遍历时建议捕获 fs::filesystem_error 异常(例如权限拒绝),尤其在不可信路径上。
编译与注意事项
需显式链接标准库的 filesystem 组件:
- Clang/GCC:加
-lstdc++fs(GCC 9+ 可能不需要)或-lc++fs(Clang + libc++) - MSVC:默认支持,无需额外链接
- 确保编译器启用 C++17:
-std=c++17 - 头文件必须写全:
#include,并建议用namespace fs = std::filesystem;简化书写
该库不提供文本读写能力——读写文件内容仍需 或第三方库;它专注路径管理与元数据操作。










