std::filesystem::directory_iterator în C++

Parcurge fișierele și directoarele dintr-un director; varianta recursive intră și în subdirectoare.

Sintaxă
for (const auto& intrare : std::filesystem::directory_iterator(director)) { ... }
for (const auto& intrare : std::filesystem::recursive_directory_iterator(director)) { ... }

Ce face std::filesystem::directory_iterator

directory_iterator(d) se folosește într-un for și dă câte o intrare (directory_entry) pentru fiecare fișier sau subdirector din d. Fiecare intrare are path(), is_regular_file(), is_directory(), file_size().

recursive_directory_iterator(d) parcurge și toate subdirectoarele, la orice adâncime; depth() spune la ce nivel ești.

Ordinea în care apar fișierele nu este garantată (depinde de sistemul de fișiere). Dacă ai nevoie de o ordine anume, pune numele într-un vector și sortează-l, cum fac exemplele de mai jos.

Parametri

Parametru Descriere
director Calea directorului parcurs.

Ce returnează

Un iterator; fiecare element este un std::filesystem::directory_entry.

Exemple

Exemplul 1: Fișierele dintr-un director, sortate

#include <algorithm>
#include <filesystem>
#include <fstream>
#include <print>
#include <string>
#include <vector>

int main() {
    namespace fs = std::filesystem;
    fs::create_directories("poze/2024");
    std::ofstream("poze/munte.jpg") << "12345";
    std::ofstream("poze/mare.jpg") << "123";
    std::ofstream("poze/lista.txt") << "12";

    std::vector<std::string> linii;
    for (const auto& intrare : fs::directory_iterator("poze")) {
        if (intrare.is_directory()) {
            linii.push_back(intrare.path().filename().string() + "/ (director)");
        } else {
            linii.push_back(std::format("{} ({} octeți)", intrare.path().filename().string(), intrare.file_size()));
        }
    }
    std::ranges::sort(linii);
    for (const auto& l : linii) std::println("{}", l);

    fs::remove_all("poze");
}

Rezultat

2024/ (director)
lista.txt (2 octeți)
mare.jpg (3 octeți)
munte.jpg (5 octeți)

Exemplul 2: Parcurgere recursivă: doar fișierele .txt

#include <algorithm>
#include <filesystem>
#include <fstream>
#include <print>
#include <string>
#include <vector>

int main() {
    namespace fs = std::filesystem;
    fs::create_directories("notite/scoala/mate");
    std::ofstream("notite/idei.txt") << "x";
    std::ofstream("notite/scoala/orar.txt") << "x";
    std::ofstream("notite/scoala/mate/formule.txt") << "x";
    std::ofstream("notite/scoala/poza.png") << "x";

    std::vector<std::string> gasite;
    for (const auto& intrare : fs::recursive_directory_iterator("notite")) {
        if (intrare.is_regular_file() && intrare.path().extension() == ".txt") {
            gasite.push_back(intrare.path().generic_string());
        }
    }
    std::ranges::sort(gasite);
    for (const auto& f : gasite) std::println("{}", f);

    fs::remove_all("notite");
}

Rezultat

notite/idei.txt
notite/scoala/mate/formule.txt
notite/scoala/orar.txt

Greșeli frecvente

  • Te bazezi pe ordinea în care iteratorul returnează fișierele. Pe alt calculator sau alt sistem de fișiere ordinea poate fi diferită; sortează explicit.
  • Ștergi sau creezi fișiere în director în timp ce îl parcurgi. Nu este specificat dacă iteratorul vede modificările; colectează întâi căile, apoi modifică.

Comenzi înrudite