std::filesystem::recursive_directory_iterator
定义于头文件 <filesystem> |
||
class recursive_directory_iterator; |
(C++17 起) | |
recursive_directory_iterator
是一个 LegacyInputIterator(传统输入迭代器),它迭代目录的 directory_entry(目录条目) 元素,并递归地迭代所有子目录的条目。迭代顺序未指定,但每个目录条目只访问一次。
默认情况下,符号链接不会被跟随,但这可以通过在构造时指定目录选项 follow_directory_symlink(跟随目录符号链接) 来启用。
特殊的路径名 dot(`.`) 和 dot-dot(`..`) 会被跳过。
如果 recursive_directory_iterator
报告错误或推进到顶层目录的最后一个目录条目之后,它将变得等于默认构造的迭代器,也称为结束迭代器。两个结束迭代器始终相等,解引用或递增结束迭代器是未定义行为。
如果在递归目录迭代器创建后,目录树中删除或添加了文件或目录,则未指定是否会通过迭代器观察到更改。
如果目录结构包含循环,则结束迭代器可能不可达。
内容 |
[编辑] 成员类型
成员类型 | 定义 |
value_type
|
std::filesystem::directory_entry |
difference_type
|
std::ptrdiff_t |
pointer
|
const std::filesystem::directory_entry* |
reference
|
const std::filesystem::directory_entry& |
iterator_category
|
std::input_iterator_tag |
[编辑] 成员函数
构造一个递归目录迭代器 (公开成员函数) | |
(析构函数) |
默认析构函数 (公开成员函数) |
观察器 | |
访问指向的条目 (公开成员函数) | |
返回当前活动的、影响迭代的选项 (公开成员函数) | |
返回当前递归深度 (公开成员函数) | |
检查是否为当前目录禁用了递归 (公开成员函数) | |
修改器 | |
赋值内容 (公开成员函数) | |
前进到下一个条目 (公开成员函数) | |
将迭代器在目录层次结构中向上移动一级 (公开成员函数) | |
禁用递归,直到下一次递增 (公开成员函数) |
[编辑] 非成员函数
基于范围的 for 循环支持 (函数) |
此外,operator==
和 operator!=
被(C++20 前)operator==
是(C++20 起) 根据 LegacyInputIterator(传统输入迭代器) 的要求提供。
未指定 是否提供 operator!=
,因为它可以通过 operator==
合成,以及(C++20 起) 相等运算符是成员还是非成员。
[编辑] 辅助特化
template<> constexpr bool |
(C++20 起) | |
template<> constexpr bool |
(C++20 起) | |
这些针对 recursive_directory_iterator
的特化使其成为 borrowed_range(借用范围)
和 view(视图)
。
[编辑] 注释
recursive_directory_iterator
通常持有一个引用计数的指针(为了满足 LegacyInputIterator(传统输入迭代器) 的浅拷贝语义),指向一个实现对象,该对象持有
- 一个非递归 directory_iterator(目录迭代器) 的容器(例如 std::vector),该容器形成递归堆栈,
- 递归深度计数器(可通过 depth() 访问),
- 构造时使用的目录选项(可通过 options() 访问),
- 待处理的递归标志(可通过 recursion_pending() 访问,可以与目录选项结合以节省空间)。
[编辑] 示例
#include <filesystem> #include <fstream> #include <iostream> #include <string> namespace fs = std::filesystem; int main() { std::filesystem::current_path(std::filesystem::temp_directory_path()); std::filesystem::create_directories("sandbox/a/b"); std::ofstream("sandbox/file1.txt"); std::filesystem::create_symlink("a", "sandbox/syma"); // Iterate over the std::filesystem::directory_entry elements explicitly auto entry_length{3UZ}; for (const fs::directory_entry& dir_entry : fs::recursive_directory_iterator("sandbox")) { std::cout << dir_entry << '\n'; if (auto l{dir_entry.path().string().length()}; entry_length < l) entry_length = l; } std::cout << std::string(entry_length + 2, '-') << '\n'; // Iterate over the std::filesystem::directory_entry elements using `auto` for (auto const& dir_entry : fs::recursive_directory_iterator("sandbox")) std::cout << dir_entry << '\n'; std::filesystem::remove_all("sandbox"); }
可能的输出
"sandbox/syma" "sandbox/file1.txt" "sandbox/a" "sandbox/a/b" ------------------- "sandbox/syma" "sandbox/file1.txt" "sandbox/a" "sandbox/a/b"
[编辑] 缺陷报告
以下行为变更的缺陷报告被追溯应用于先前发布的 C++ 标准。
DR | 应用于 | 已发布行为 | 正确行为 |
---|---|---|---|
LWG 3480 | C++20 | recursive_directory_iterator 既不是 borrowed_range(借用范围) 也不是 view(视图) |
它两者都是 |
[编辑] 另请参阅
(C++17) |
指向目录内容的迭代器 (类) |
(C++17) |
一个目录条目 (类) |
(C++17) |
用于迭代目录内容的选项 (枚举) |