Namensräume
Varianten
Aktionen

std::filesystem::recursive_directory_iterator

Von cppreference.com
 
 
 
 
Definiert in Header <filesystem>
class recursive_directory_iterator;
(seit C++17)

recursive_directory_iterator ist ein LegacyInputIterator, der über die directory_entry-Elemente eines Verzeichnisses und rekursiv über die Einträge aller Unterverzeichnisse iteriert. Die Iterationsreihenfolge ist nicht spezifiziert, außer dass jeder Verzeichniseintrag nur einmal besucht wird.

Standardmäßig werden Symlinks nicht verfolgt, dies kann jedoch durch Angabe der Verzeichnissoption follow_directory_symlink zur Konstruktionszeit aktiviert werden.

Die speziellen Pfadnamen dot und dot-dot werden übersprungen.

Wenn der recursive_directory_iterator einen Fehler meldet oder über den letzten Verzeichniseintrag des obersten Verzeichnisses hinaus fortgeschritten wird, wird er gleich dem standardkonstruierten Iterator, auch End-Iterator genannt. Zwei End-Iteratoren sind immer gleich, das Dereferenzieren oder Inkrementieren des End-Iterators ist undefiniertes Verhalten.

Wenn eine Datei oder ein Verzeichnis nach der Erstellung des rekursiven Verzeichnisiterators gelöscht oder zum Verzeichnisbaum hinzugefügt wird, ist es nicht spezifiziert, ob die Änderung über den Iterator beobachtet wird.

Wenn die Verzeichnisstruktur Zyklen enthält, kann der End-Iterator unerreichbar sein.

Inhalt

[edit] Member types

Mitgliedertyp Definition
value_type std::filesystem::directory_entry
difference_type std::ptrdiff_t
Zeiger const std::filesystem::directory_entry*
Referenz const std::filesystem::directory_entry&
iterator_category std::input_iterator_tag

[edit] Member functions

konstruiert einen rekursiven Verzeichnisiterator
(public member function) [edit]
(Destruktor)
standardmäßiger Destruktor
(public member function) [edit]
Observer
greift auf den Zeigereintrag zu
(public member function) [edit]
gibt die aktuell aktiven Optionen zurück, die die Iteration beeinflussen
(public member function) [edit]
gibt die aktuelle Rekursionstiefe zurück
(public member function) [edit]
prüft, ob die Rekursion für das aktuelle Verzeichnis deaktiviert ist
(public member function) [edit]
Modifizierer
weist Inhalte zu
(public member function) [edit]
bewegt sich zum nächsten Eintrag
(public member function) [edit]
verschiebt den Iterator eine Ebene in der Verzeichnishierarchie nach oben
(public member function) [edit]
deaktiviert die Rekursion bis zum nächsten Inkrement
(public member function) [edit]

[edit] Nicht-Member-Funktionen

Unterstützung für range-basierte for-Schleifen
(Funktion) [bearbeiten]

Zusätzlich werden operator== und operator!=(bis C++20)operator==(seit C++20) als für LegacyInputIterator erforderlich bereitgestellt.

Es ist nicht spezifiziert ob operator!= bereitgestellt wird, da es aus operator== synthetisiert werden kann, und(seit C++20) ob ein Gleichheitsoperator ein Member oder Nicht-Member ist.

[edit] Hilfs-Spezialisierungen

template<>

constexpr bool

    ranges::enable_borrowed_range<std::filesystem::recursive_directory_iterator> = true;
(seit C++20)
template<>

constexpr bool

    ranges::enable_view<std::filesystem::recursive_directory_iterator> = true;
(seit C++20)

Diese Spezialisierungen für recursive_directory_iterator machen ihn zu einem borrowed_range und einer view.

[edit] Anmerkungen

Ein recursive_directory_iterator hält typischerweise einen referenzgezählten Zeiger (um die flache Kopiersemantik von LegacyInputIterator zu erfüllen) auf ein Implementierungsobjekt, das Folgendes enthält:

  • einen Container (wie z. B. std::vector) von nicht-rekursiven directory_iterators, der den Rekursionsstapel bildet,
  • den Rekursionstiefenzähler (zugänglich über depth()),
  • die zur Konstruktion verwendeten Verzeichnissoptionen (zugänglich über options()),
  • das Flag für ausstehende Rekursion (zugänglich über recursion_pending(), kann zur Platzersparnis mit den Verzeichnissoptionen kombiniert werden).

[edit] Beispiel

#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");
}

Mögliche Ausgabe

"sandbox/syma"
"sandbox/file1.txt"
"sandbox/a"
"sandbox/a/b"
-------------------
"sandbox/syma"
"sandbox/file1.txt"
"sandbox/a"
"sandbox/a/b"

[edit] Fehlerberichte

Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
LWG 3480 C++20 recursive_directory_iterator war weder ein borrowed_range noch eine view es ist beides

[edit] Siehe auch

ein Iterator für den Inhalt des Verzeichnisses
(Klasse) [bearbeiten]
ein Verzeichniseintrag
(Klasse) [bearbeiten]
Optionen für das Iterieren über Verzeichnisinhalte
(Enum) [bearbeiten]