std::filesystem::recursive_directory_iterator默认跳过符号链接、深度优先遍历;需显式指定directory_options::follow_directory_symlink才跟随软链接;可用disable_recursion_pending()跳过指定子目录。

std::filesystem::recursive_directory_iterator 怎么用
直接构造就能开始遍历,它默认自动跳过符号链接(不跟随),且会按深度优先顺序进入子目录。关键点是:必须用 std::filesystem::directory_options::follow_directory_symlink 才能跟随软链接;否则遇到 symlink 会跳过——这点容易被忽略,尤其在跨平台调试时。
基础写法:
for (auto it = std::filesystem::recursive_directory_iterator("/path"); it != std::filesystem::end(it); ++it) {
std::cout << it->path() << "\n";
}
如何跳过特定子目录(比如 .git、build)
迭代器本身不提供过滤接口,得靠手动判断 it->path().filename() 或 it->path().string(),再配合 it.disable_recursion_pending() 阻止进入当前项(仅对目录有效)。
常见做法:
立即学习“C++免费学习笔记(深入)”;
- 在循环体内检查
it->is_directory() - 若目录名匹配黑名单(如
"build"、".git"),调用it.disable_recursion_pending() - 注意:该调用只对当前迭代位置生效,必须在 ++it 前执行
示例片段:
for (auto it = std::filesystem::recursive_directory_iterator("/src"); it != std::filesystem::end(it); ++it) {
if (it->is_directory()) {
auto name = it->path().filename().string();
if (name == ".git" || name == "build" || name == "__pycache__") {
it.disable_recursion_pending();
continue;
}
}
std::cout << it->path() << "\n";
}
遍历时抛出 filesystem_error 怎么处理
权限不足、路径被删除、挂载点失效等都会触发 std::filesystem::filesystem_error 异常。默认情况下,迭代器遇到错误会直接 throw,导致遍历中断。
解决方式只有两种:
- 用
std::filesystem::directory_options::skip_permission_denied选项构造迭代器,跳过无权访问的条目 - 捕获异常并重置迭代器(不推荐,因标准未保证异常后迭代器状态可恢复)
安全写法:
try {
for (auto it = std::filesystem::recursive_directory_iterator(
"/home/user", std::filesystem::directory_options::skip_permission_denied);
it != std::filesystem::end(it); ++it) {
std::cout << it->path() << "\n";
}
} catch (const std::filesystem::filesystem_error& e) {
std::cerr << "FS error: " << e.what() << "\n";
}
Windows 下路径分隔符和长路径要注意什么
Windows 默认限制 MAX_PATH=260,而 std::filesystem 在启用 long path 支持的前提下才能处理超过该长度的路径。需要确认两点:
- 编译时链接器设置:MSVC 需开启
/Zc:wchar_t和 Unicode 支持 - 系统级配置:Windows 10+ 要在组策略或注册表中启用
LongPathsEnabled -
it->path()返回的是std::filesystem::path,其c_str()在 Windows 上返回wchar_t*,不能直接传给 ANSI C 函数
跨平台安全输出建议用:
std::wcout << it->path() << L"\n"; // Windows // 或转为 UTF-8 字符串(需 std::filesystem::path::u8string(),C++20 起)递归遍历看似简单,但权限控制、符号链接行为、异常恢复、长路径兼容这四点,在真实项目里几乎每次都会踩到至少一个。尤其是
disable_recursion_pending() 的调用时机和 skip_permission_denied 的选项位置,错一个字符就可能漏掉整个子树或 crash。











