命名空间
变体
操作

std::filesystem::recursive_directory_iterator

来自 cppreference.com
 
 
 
 
定义在头文件 <filesystem>
class recursive_directory_iterator;
(自 C++17 起)

recursive_directory_iterator 是一个 LegacyInputIterator,它遍历目录的 directory_entry 元素,并递归遍历所有子目录的条目。迭代顺序未指定,但每个目录条目只访问一次。

默认情况下,不会跟踪符号链接,但可以通过在构造时指定目录选项 follow_directory_symlink 来启用它。

特殊路径名 dotdot-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 起) 等于运算符是成员还是非成员也是未指定的。

[编辑] 辅助模板

namespace std::ranges {

template<>
inline constexpr bool
    enable_borrowed_range<std::filesystem::recursive_directory_iterator> = true;

}
(自 C++20 起)
namespace std::ranges {

template<>
inline constexpr bool
    enable_view<std::filesystem::recursive_directory_iterator> = true;

}
(自 C++20 起)

recursive_directory_iterator 的这些特化使其成为一个 borrowed_range 和一个 view

[编辑] 注释

一个 recursive_directory_iterator 通常保存一个引用计数的指针(为了满足 LegacyInputIterator 的浅拷贝语义),该指针指向一个实现对象,该对象保存

  • 一个容器(例如 std::vector),其中包含形成递归栈的非递归 directory_iterators
  • 递归深度计数器(可以使用 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 它两者都是

[编辑] 参见

指向目录内容的迭代器
(类) [编辑]
目录项
(类) [编辑]
迭代目录内容的选项
(枚举) [编辑]