std::filesystem: Portable File Operations
C++17 introduced <filesystem> for portable, type-safe file and directory operations, replacing platform-specific APIs.
Path Manipulation
#include <filesystem>
namespace fs = std::filesystem;
fs::path p = "/home/user/document.txt";
p.filename(); // "document.txt"
p.stem(); // "document"
p.extension(); // ".txt"
p.parent_path(); // "/home/user"
p.root_path(); // "/"
// Path concatenation
fs::path dir = "/home/user";
fs::path file = "document.txt";
fs::path full = dir / file; // "/home/user/document.txt"
Path Components
fs::path p = "/home/user/docs/file.txt";
for (const auto& part : p) {
std::cout << part << ' ';
}
// Output: "/" "home" "user" "docs" "file.txt"
Checking File Status
fs::path p = "some/path";
fs::exists(p); // Does path exist?
fs::is_regular_file(p); // Is it a regular file?
fs::is_directory(p); // Is it a directory?
fs::is_symlink(p); // Is it a symbolic link?
fs::is_empty(p); // Is file empty or directory empty?
// File size
auto size = fs::file_size(p); // In bytes
// Last modification time
auto time = fs::last_write_time(p);
Directory Iteration
// Iterate over directory contents
for (const auto& entry : fs::directory_iterator("/path/to/dir")) {
std::cout << entry.path() << '\n';
}
// Recursive iteration
for (const auto& entry : fs::recursive_directory_iterator("/path/to/dir")) {
if (fs::is_regular_file(entry)) {
std::cout << entry.path() << ": " << fs::file_size(entry) << " bytes\n";
}
}
File Operations
// Copy file
fs::copy("source.txt", "dest.txt");
// Copy with options
fs::copy("source.txt", "dest.txt",
fs::copy_options::overwrite_existing);
// Rename/move
fs::rename("old_name.txt", "new_name.txt");
// Remove file
fs::remove("file.txt");
// Remove directory and contents
fs::remove_all("directory");
// Create directory
fs::create_directory("new_dir");
// Create directory and parents
fs::create_directories("path/to/deep/dir");
File Permissions
fs::path p = "file.txt";
// Get permissions
auto perms = fs::status(p).permissions();
// Set permissions
fs::permissions(p, fs::perms::owner_read | fs::perms::owner_write);
// Add permissions
fs::permissions(p, fs::perms::others_read, fs::perm_options::add);
// Remove permissions
fs::permissions(p, fs::perms::others_write, fs::perm_options::remove);
Space Information
fs::space_info info = fs::space("/");
std::cout << "Capacity: " << info.capacity << " bytes\n";
std::cout << "Free: " << info.free << " bytes\n";
std::cout << "Available: " << info.available << " bytes\n";
Current Path
// Get current working directory
fs::path cwd = fs::current_path();
// Set current working directory
fs::current_path("/new/path");
Temporary Directory
fs::path temp = fs::temp_directory_path();
fs::path temp_file = temp / "my_temp_file.txt";
Error Handling
// Exception-based
try {
fs::copy("source.txt", "dest.txt");
} catch (const fs::filesystem_error& e) {
std::cerr << e.what() << '\n';
std::cerr << "Path1: " << e.path1() << '\n';
std::cerr << "Path2: " << e.path2() << '\n';
}
// Error code-based
std::error_code ec;
fs::copy("source.txt", "dest.txt", ec);
if (ec) {
std::cerr << "Error: " << ec.message() << '\n';
}
Practical Examples
Find All Files with Extension
std::vector<fs::path> find_files(const fs::path& dir, const std::string& ext) {
std::vector<fs::path> result;
for (const auto& entry : fs::recursive_directory_iterator(dir)) {
if (entry.path().extension() == ext) {
result.push_back(entry.path());
}
}
return result;
}
auto cpp_files = find_files("/project", ".cpp");
Calculate Directory Size
uintmax_t directory_size(const fs::path& dir) {
uintmax_t size = 0;
for (const auto& entry : fs::recursive_directory_iterator(dir)) {
if (fs::is_regular_file(entry)) {
size += fs::file_size(entry);
}
}
return size;
}
Safe File Backup
void backup_file(const fs::path& source) {
if (!fs::exists(source)) return;
fs::path backup = source;
backup += ".bak";
if (fs::exists(backup)) {
fs::remove(backup);
}
fs::copy(source, backup);
}
Conceptual Check
What operator is used to concatenate filesystem paths?
Runtime Environment
Interactive Lab
1#include <iostream>
2#include <filesystem>
3
4namespace fs = std::filesystem;
5
6int main() {
7 fs::path p = "/home/user/document.txt";
8
9 std::cout << "Full path: " << p << '\n';
10 std::cout << "Filename: " << p.filename() << '\n';
11 std::cout << "Stem: " << p.stem() << '\n';
12 std::cout << "Extension: " << p.extension() << '\n';
13 std::cout << "Parent: " << p.parent_path() << '\n';
14
15 // Path concatenation
16 fs::path dir = "/tmp";
17 fs::path file = "test.txt";
18 fs::path full = dir / file;
19 std::cout << "Concatenated: " << full << '\n';
20
21 // Get temp directory
22 std::cout << "Temp directory: " << fs::temp_directory_path() << '\n';
23
24 return 0;
25}
System Console
Waiting for signal...