std::filesystem::recursive_directory_iterator可自动递归遍历子目录,基础用法为构造后用范围for遍历,注意默认跳过符号链接,需显式指定选项才能跟随。

std::filesystem::recursive_directory_iterator 怎么用
直接上手就用 std::filesystem::recursive_directory_iterator,它能自动递归进子目录,比手动写栈或队列遍历省事得多。注意它默认跳过符号链接(除非显式传 std::filesystem::directory_options::follow_directory_symlink),这点容易被忽略。
基础用法就是构造迭代器、范围 for 遍历:
for (const auto& entry : std::filesystem::recursive_directory_iterator("/path/to/dir")) {
if (entry.is_regular_file()) {
std::cout
- 迭代器构造失败会抛
std::filesystem::filesystem_error,比如路径不存在或没权限,必须捕获 - 如果只想遍历当前目录一层,用
std::filesystem::directory_iterator,别误用 recursive 版本 - Windows 下路径分隔符用
/或\都行,std::filesystem::path会自动 normalize
怎么跳过特定目录或文件(比如 .git、node_modules)
std::filesystem::recursive_directory_iterator 不支持内置过滤,得靠手动 continue。关键点是:在循环里判断 entry.path().filename() 或 entry.path().string(),但别用 entry.path().parent_path() 做字符串匹配——容易漏掉嵌套路径。
推荐写个简单白名单/黑名单函数:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
bool should_skip(const std::filesystem::directory_entry& entry) {
auto name = entry.path().filename().string();
static const std::unordered_set<:string> skip_dirs = {".git", "node_modules", "__pycache__"};
return entry.is_directory() && skip_dirs.count(name);
}</:string>
- 调用时加
if (should_skip(entry)) continue;即可 - 不要在循环里调
entry.symlink_status()多余查状态,entry.is_directory()已足够快 - 如果跳过逻辑复杂(如通配符匹配),建议用
std::regex,但注意性能损耗
遍历时遇到权限错误或损坏符号链接怎么办
默认情况下,只要某个子目录不可读,整个迭代就会抛异常并中断。要继续遍历其他路径,必须启用“不抛错”模式:构造迭代器时传 std::filesystem::directory_options::skip_permission_denied。
完整健壮写法:
try {
for (auto iter = std::filesystem::recursive_directory_iterator("/path",
std::filesystem::directory_options::skip_permission_denied);
iter != std::filesystem::end(iter); ++iter) {
// 处理 entry
}
} catch (const std::filesystem::filesystem_error& e) {
// 只有构造时路径根本不存在等致命错误才会到这里
std::cerr
-
skip_permission_denied只跳过 EACCES 类错误,对 ENOENT(文件已删)或 ELOOP(坏软链)仍可能抛异常 - 如果想连软链解析失败也跳过,得在外层 try/catch 每次
entry.path()或entry.status()调用 - Windows 上某些系统目录(如
C:System Volume Information)即使管理员权限也无法进入,只能靠 skip_option 屏蔽
性能和跨平台要注意什么
Linux/macOS 下 recursive_directory_iterator 底层用 fts_open 或 openat+getdents,基本无额外开销;Windows 下走 FindFirstFileExW,也够快。但真正在意性能时,别在循环里反复调 entry.path().string() 或 entry.path().filename().string() —— std::filesystem::path 对象本身支持比较和成员访问,尽量复用。
- 避免在循环内做磁盘 I/O,比如反复调
entry.file_size()(虽然缓存了,但仍有 syscall 开销) - Clang 10+/GCC 8+ 支持,MSVC 2019 16.5+ 才完全稳定;老版本可能缺失
skip_permission_denied或抛异常行为不一致 - 如果目标环境不确定是否启用了
-lstdc++fs(GCC)或需要额外链接(如 macOS 的-lc++fs),编译报undefined reference to std::filesystem::...就得补链接参数
最麻烦的其实是路径编码:Windows 上宽字符路径由库内部处理,但如果你把 entry.path().string() 当作 UTF-8 用,在非 UTF-8 系统区域设置下可能出乱码——稳妥做法是统一用 entry.path().u8string() 获取 UTF-8 字符串。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










