C++17stladvanced
std::filesystem::recursive_directory_iterator
C++17 · Practical Modern · Compiler flag: -std=c++17
Explanation
Similar to `directory_iterator` but descends into subdirectories recursively, visiting the entire directory tree beneath a given root path.
Real-World Scenario
Search for all `.log` files across an entire project directory tree for a log aggregation tool.
Quick Snippet
snippet.cpp
#include <filesystem>
namespace fs = std::filesystem;
for (const auto& entry : fs::recursive_directory_iterator("/var/log")) {
if (entry.path().extension() == ".log") {
std::cout << entry.path() << "\n";
}
}Full Example
recursive_directory_iterator.cpp
// CodeNebula - C++17 Example: std::filesystem::recursive_directory_iterator
// Compile: g++ -std=c++17 -Wall -Wextra -o example recursive_directory_iterator.cpp -lstdc++fs
// recursive_directory_iterator traverses a directory tree recursively,
// visiting all files and subdirectories at every nesting level.
#include <iostream>
#include <filesystem>
#include <fstream>
namespace fs = std::filesystem;
int main() {
try {
// Setup: create a nested directory structure
fs::path base = fs::temp_directory_path() / "cn_recur_iter";
fs::create_directories(base / "src" / "core");
fs::create_directories(base / "include");
{ std::ofstream(base / "README.md") << "readme"; }
{ std::ofstream(base / "src" / "main.cpp") << "main"; }
{ std::ofstream(base / "src" / "core" / "engine.cpp") << "engine"; }
{ std::ofstream(base / "include" / "header.h") << "header"; }
// --- Basic recursive iteration ---
std::cout << "=== Recursive traversal ===" << std::endl;
for (const auto& entry : fs::recursive_directory_iterator(base)) {
std::string indent(entry.depth() * 2, ' ');
std::cout << indent << entry.path().filename().string()
<< (entry.is_directory() ? "/" : "") << std::endl;
}
// --- Depth information ---
std::cout << "\n=== Depth info ===" << std::endl;
for (auto it = fs::recursive_directory_iterator(base);
it != fs::recursive_directory_iterator(); ++it) {
std::cout << "depth=" << it.depth() << " : "
<< it->path().filename().string() << std::endl;
}
// --- Count files vs directories ---
std::cout << "\n=== Statistics ===" << std::endl;
int files = 0, dirs = 0;
for (const auto& entry : fs::recursive_directory_iterator(base)) {
if (entry.is_regular_file()) ++files;
else if (entry.is_directory()) ++dirs;
}
std::cout << "Total files: " << files << std::endl;
std::cout << "Total directories: " << dirs << std::endl;
// --- Disable recursion on specific directories ---
std::cout << "\n=== Skip recursion into 'src' ===" << std::endl;
for (auto it = fs::recursive_directory_iterator(base);
it != fs::recursive_directory_iterator(); ++it) {
if (it->is_directory() && it->path().filename() == "src") {
std::cout << "[skipping] " << it->path().filename().string() << "/" << std::endl;
it.disable_recursion_pending();
} else {
std::cout << it->path().filename().string() << std::endl;
}
}
// Cleanup
fs::remove_all(base);
} catch (const fs::filesystem_error& e) {
std::cerr << "Filesystem error: " << e.what() << std::endl;
}
return 0;
}
/*
Expected output (order may vary by OS):
=== Recursive traversal ===
README.md
include/
header.h
src/
core/
engine.cpp
main.cpp
=== Depth info ===
depth=0 : README.md
depth=0 : include
depth=1 : header.h
depth=0 : src
depth=1 : core
depth=2 : engine.cpp
depth=1 : main.cpp
=== Statistics ===
Total files: 4
Total directories: 3
=== Skip recursion into 'src' ===
README.md
include
header.h
[skipping] src/
*/
Run command
g++ -std=c++17 -Wall -Wextra -o example recursive_directory_iterator.cpp -lstdc++fs