应使用 std::filesystem::recursive_directory_iterator 遍历子目录和文件,它自动深度优先遍历并支持跳过权限错误;需处理 filesystem_error 异常或设置 skip_permission_denied 选项。
std::filesystem 遍历子目录和文件直接用 std::filesystem::recursive_directory_iterator,它会自动进入子目录,按深度优先顺序返回所有 directory_entry。别手写递归——容易漏掉符号链接、权限错误或循环引用。
常见错误是没捕获异常:access_denied 或 not_a_directory 会抛 std::filesystem::filesystem_error,不处理就 crash。默认构造的迭代器不跳过异常,得手动加 try/catch 或用 std::filesystem::directory_options::skip_permission_denied。
for (auto& entry : std::filesystem::recursive_directory_iterator(path, std::filesystem::directory_options::skip_permission_denied)) {
if (entry.is_regular_f
ile()) {
std::cout << entry.path() << "\n";
}
}std::filesystem::directory_iterator,它不进子目录std::filesystem::is_directory 和 is_regular_file 判断不准?不是函数不准,是调用前没确认 entry 状态是否已缓存。directory_entry 默认惰性加载元数据,首次调用 is_* 才去查系统。如果中间路径被删/权限变,可能抛异常;更糟的是,某些平台(如 Windows)对符号链接默认不解析,is_directory() 返回 false 即使它指向一个目录。
entry.status() 或 entry.symlink_status(),再判断类型status() 查链接目标,symlink_status() 查链接本身is_directory() 误判,必须用 symlink_status().type() == std::filesystem::file_type::directory
std::filesystem::path 内部统一用 / 存储,无论 Windows 还是 Linux,path.native() 才转成本地格式(Windows 上变成 \)。但真正要注意的是字符编码:Windows API 默认用当前代码页(如 GBK),而 C++17 标准要求 std::filesystem 接收 UTF-8 字符串(GCC/Clang)或宽字符(MSVC)。
std::string 安全std::wstring 构造 path,否则含中文路径可能失败+:用 / 操作符,例如 p / "sub" / "file.txt",它自动处理分隔符cout :用 p.string()(UTF-8)或 p.wstring()(宽字符)显式转换
慢通常不是 recursive_directory_iterator 本身的问题,而是每步都触发系统调用查元数据。比如只想要文件名,却反复调 entry.is_regular_file(),等于每个 entry 都 stat 一次。
entry.file_size() 前先确认类型,或批量用 std::filesystem::status(entry) 一次取回全部信息directory_iterator + 手动栈管理,避免深度优先的隐式调用开销path 对象,复用变量减少临时对象分配最常被忽略的一点:std::filesystem 在 GCC 需要链接 -lstdc++fs,Clang 要 -lc++fs,MSVC 默认开启但需确保项目设置为 C++17 或更高。忘了加链接选项,编译通过但运行时报 undefined symbol。