filesystem (C++17)
Prerequisites
1. What is a filesystem?
<filesystem> provides a standard, portable way to work with files and directories.
Before C++17:
- OS-specific APIs (POSIX / Windows)
- Boost.Filesystem
Now:
- Built into the standard library
- Cross-platform
1
2
3
| #include <filesystem>
namespace fs = std::filesystem;
|
| Component | Description |
|---|
fs::path | represents file path |
fs::directory_iterator | iterate directory |
fs::exists | check existence |
fs::create_directory | create folder |
fs::remove | delete file |
fs::file_size | get file size |
Use it when:
- file/directory manipulation
- cross-platform file handling
- writing tools, scripts, utilities
- logging, file scanning
2. filesystem functions
fs::path
Represents a file system path.
1
| fs::path p = "folder/file.txt";
|
1
2
3
4
| p.filename(); // "file.txt"
p.extension(); // ".txt"
p.stem(); // "file"
p.parent_path(); // "folder"
|
1
2
| fs::path p = "folder";
p /= "file.txt"; // folder/file.txt
|
/= is preferred over string concatenation
Checking Files
1
2
| if (fs::exists("file.txt"))
std::cout << "File exists\n";
|
Type Check
1
2
| fs::is_regular_file(p);
fs::is_directory(p);
|
Directory Operations
Create Directory
1
| fs::create_directory("new_folder");
|
Create Nested
1
| fs::create_directories("a/b/c");
|
Remove
1
2
| fs::remove("file.txt"); // file
fs::remove_all("folder"); // recursive
|
Iterating Directory
1
2
| for (const auto& entry : fs::directory_iterator("folder"))
std::cout << entry.path() << "\n";
|
1
2
3
4
5
6
7
8
9
10
| folder/
├── a.txt
├── b.txt
└── sub/
└── c.txt
Result:
folder/a.txt
folder/b.txt
folder/sub
|
Recursive Iteration
1
2
| for (const auto& entry : fs::recursive_directory_iterator("folder"))
std::cout << entry.path() << "\n";
|
1
2
3
4
5
6
7
8
9
10
11
| folder/
├── a.txt
├── b.txt
└── sub/
└── c.txt
Result:
folder/a.txt
folder/b.txt
folder/sub
folder/sub/c.txt
|
File Size & Info
1
| auto size = fs::file_size("file.txt");
|
Last Modified Time
1
| auto time = fs::last_write_time("file.txt");
|
Copy / Move Files
1
| fs::copy("source.txt", "dest.txt");
|
Move / Rename
1
| fs::rename("old.txt", "new.txt");
|
Error Handling
1
2
3
4
5
6
7
8
| try
{
fs::remove("file.txt");
}
catch (const fs::filesystem_error& e)
{
std::cout << e.what();
}
|
Non-throwing Version
1
2
3
4
5
| std::error_code ec;
fs::remove("file.txt", ec);
if (ec)
std::cout << ec.message();
|
System Calls
Many operations call the OS:
existsfile_sizedirectory_iterator
These are relatively expensive
- Avoid repeated
exists() calls - Cache results if possible
- Prefer batch operations