Main
- Preface
- Chapter 01: Towards Modern C++
- Chapter 02: Language Usability Enhancements
- Chapter 03: Language Runtime Enhancements
- Chapter 04: Containers
- Chapter 05: Smart Pointers and Memory Management
- Chapter 06: Regular Expression
- Chapter 07: Parallelism and Concurrency
- Chapter 08: File System
- Chapter 09: Minor Features
- Chapter 10: C++20
- Chapter 11: C++23
- Chapter 12: C++26 (Outlook)
- Appendix 1: Further Study Materials
- Appendix 2: Modern C++ Best Practices
- Appendix 3: Modern C++ Feature Index
Chapter 08: File System
The file system library provides functions related to
the operation of the file system, path, regular files, directories, and so on.
Similar to the regular expression library, it was one of the first libraries
to be launched by boost and eventually merged into the C++ standard in C++17.
Its entire contents live in the <filesystem> header under the
std::filesystem namespace, for which a short alias is conventionally introduced:
#include <filesystem> |
On some older toolchains (e.g. GCC before version 8), using the filesystem library also required linking against
-lstdc++fs(or LLVM's-lc++fs); modern compilers no longer need this.
8.1 The path std::filesystem::path
std::filesystem::path is the heart of the library. It represents a file path in a
portable way and hides the differences between operating systems in their path
separators (such as / and \). A path can be constructed from a string and
composed with operator/:
fs::path p = "/usr/local"; |
It is worth emphasizing that a path is only a syntactic representation of a
path: constructing one neither touches the disk nor requires the path to actually
exist. It provides a set of member functions for decomposing a path:
fs::path p = "/usr/local/hello.txt"; |
8.2 Querying file status
The library provides a set of non-member functions for querying the actual
file a path refers to; each takes a path argument:
fs::exists(p); // does the path exist |
Note that these operations, which genuinely access the file system, throw a
std::filesystem::filesystem_error on failure (e.g. the path does not exist or
permission is denied). For nearly every such function the library provides an
overload taking a std::error_code&, to report errors without exceptions:
std::error_code ec; |
8.3 Iterating directories
std::filesystem::directory_iterator iterates over the immediate entries of a
directory, while recursive_directory_iterator walks the entire directory tree.
Both can be used directly in a range-based for loop, yielding directory_entry
elements:
for (const auto& entry : fs::directory_iterator(dir)) { |
A directory_entry caches the status of the file it refers to, so member functions
such as entry.is_regular_file() and entry.file_size() are often more efficient
than calling the non-member functions again on its path.
8.4 Creating, copying, and removing
The library also offers a set of operations that modify the file system:
fs::create_directories(p / "a" / "b"); // create directories recursively |
8.5 A complete example
The following example combines the operations above. To keep it self-contained and repeatable, we create a dedicated working directory under the system temporary directory and clean it up at the end:
#include <filesystem> |
Further Readings
Changkun Ou © 2016-2026. The book is licensed under Creative Commons Attribution-NonCommercial-NoDerivatives 4.0, code is open sourced under the MIT License.
If you like the book, you could donate the author.