Spec-Zone.ru › C++

std::filesystem::directory_iterator

Определено в заголовке <filesystem>
class directory_iterator;
(с C++17)

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

Если 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

Члены-функции

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

Функции вне класса

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

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

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

Вспомогательные шаблоны

namespace std::ranges {
template<>
inline constexpr bool
    enable_borrowed_range<std::filesystem::directory_iterator> = true;
}
(с C++20)
namespace std::ranges {
template<>
inline constexpr bool 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++.

DR Применено к Поведение, как опубликовано Корректное поведение
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/w/cpp/filesystem/directory_iterator

Spec-Zone.ru

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