Spec-Zone.ru › C++

std::filesystem::directory_iterator

Определён в заголовочном файле <filesystem>
class directory_iterator;
(начиная с C++17)

directory_iterator — это LegacyInputIterator, который выполняет итерацию по элементам каталога directory_entry (но не посещает подкаталоги). Порядок итерации не определён, за исключением того, что каждая запись каталога посещается только один раз. Специальные имена путей dot и dot-dot пропускаются.

Если directory_iterator сообщает об ошибке или перемещается за последнюю запись каталога, он становится равным итератору, созданному по умолчанию, также известному как конечный итератор. Два конечных итератора всегда равны; разыменование или инкремент конечного итератора приводит к неопределённому поведению.

Если после создания итератора каталога файл или каталог удаляется из дерева каталогов либо добавляется в него, не определено, будет ли это изменение обнаружено при использовании итератора.

Типы-члены

Тип-член Определение
value_type std::filesystem::directory_entry
difference_type std::ptrdiff_t
pointer conststd::filesystem::directory_entry*
reference conststd::filesystem::directory_entry&
iterator_category std::input_iterator_tag

Функции-члены

(constructor)
создаёт итератор каталога
(функция-член класса)
(destructor)
деструктор по умолчанию
(функция-член класса)
operator=
присваивает содержимое
(функция-член класса)
operator*operator->
обращается к элементу, на который указывает итератор
(функция-член класса)
incrementoperator++
переходит к следующему элементу
(функция-член класса)

Функции, не являющиеся членами

begin(std::filesystem::directory_iterator)end(std::filesystem::directory_iterator)
(C++17)
поддержка циклов range-based for
(функция)

Кроме того, operator== и operator!= являются(до C++20)operator== является(начиная с C++20) в соответствии с требованиями LegacyInputIterator.

Не определено, предоставляется ли operator!=, поскольку его можно синтезировать из operator==, и(начиная с C++20) является ли оператор равенства функцией-членом или функцией, не являющейся членом.

Вспомогательные специализации

template<>
constexpr bool 
    ranges::enable_borrowed_range<std::filesystem::directory_iterator> = true;
(начиная с C++20)
template<>
constexpr bool 
    ranges::enable_view<std::filesystem::directory_iterator> = true;
(начиная с C++20)

Эти специализации для directory_iterator делают его borrowed_range и view.

Примечания

Многие низкоуровневые API операционных систем для обхода каталогов получают атрибуты файлов вместе со следующей записью каталога. Конструкторы и неконстантные функции-члены std::filesystem::directory_iterator сохраняют эти атрибуты, если они имеются, в объекте std::filesystem::directory_entry, на который указывает итератор, не вызывая directory_entry::refresh. Благодаря этому можно проверять атрибуты записей каталога в процессе итерации без дополнительных системных вызовов.

Пример

#include <algorithm>
#include <filesystem>
#include <fstream>
#include <iostream>

int main()
{
    const std::filesystem::path sandbox{"sandbox"};
    std::filesystem::create_directories(sandbox/"dir1"/"dir2");
    std::ofstream{sandbox/"file1.txt"};
    std::ofstream{sandbox/"file2.txt"};
 
    std::cout << "directory_iterator:\n";
    // directory_iterator can be iterated using a range-for loop
    for (auto const& dir_entry : std::filesystem::directory_iterator{sandbox}) 
        std::cout << dir_entry.path() << '\n';

    std::cout << "\ndirectory_iterator as a range:\n";
    // directory_iterator behaves as a range in other ways, too
    std::ranges::for_each(
        std::filesystem::directory_iterator{sandbox},
        [](const auto& dir_entry) { std::cout << dir_entry << '\n'; });

    std::cout << "\nrecursive_directory_iterator:\n";
    for (auto const& dir_entry : std::filesystem::recursive_directory_iterator{sandbox}) 
        std::cout << dir_entry << '\n';
 
    // delete the sandbox dir and all contents within it, including subdirs
    std::filesystem::remove_all(sandbox);
}

Возможный вывод:

directory_iterator:
"sandbox/file2.txt"
"sandbox/file1.txt"
"sandbox/dir1"

directory_iterator as a range:
"sandbox/file2.txt"
"sandbox/file1.txt"
"sandbox/dir1"

recursive_directory_iterator:
"sandbox/file2.txt"
"sandbox/file1.txt"
"sandbox/dir1"
"sandbox/dir1/dir2"

Отчёты об ошибках

Следующие отчёты об ошибках, изменяющие поведение, были ретроактивно применены к ранее опубликованным стандартам C++.

Отчёт об ошибке Применён к Поведение согласно опубликованной версии Правильное поведение
LWG 3480 C++20 directory_iterator не являлся ни borrowed_range, ни view является и тем, и другим

См. также

recursive_directory_iterator
(C++17)
итератор по содержимому каталога и его подкаталогов
(класс)
directory_options
(C++17)
параметры итерации по содержимому каталога
(перечисление)
directory_entry
(C++17)
запись каталога
(класс)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/filesystem/directory_iterator

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API