第 8 章 文件系统
文件系统库提供了文件系统、路径、常规文件、目录等等相关组件进行操作的相关功能。和正则表达式库类似,它也是最先由 boost 发起,并最终在 C++17 中被合并为 C++ 标准的众多库之一。该库的全部内容位于头文件 <filesystem> 中的 std::filesystem 命名空间下,惯例上会为其引入一个简短的别名:
#include <filesystem> |
在某些较老的工具链(如 GCC 8 之前)中,使用文件系统库还需要额外链接
-lstdc++fs(或 LLVM 的-lc++fs);现代编译器已不再需要。
8.1 路径 std::filesystem::path
std::filesystem::path 是整个库的核心,它以一种可移植的方式表示文件路径,并屏蔽了不同操作系统在路径分隔符(如 / 与 \)上的差异。path 可以由字符串构造,并通过 operator/ 来拼接路径片段:
fs::path p = "/usr/local"; |
值得强调的是,path 仅仅是对路径的语法表示,构造一个 path 并不会访问磁盘,也不要求该路径真实存在。它提供了一组用于分解路径的成员函数:
fs::path p = "/usr/local/hello.txt"; |
8.2 查询文件状态
库提供了一系列非成员函数用于查询路径对应的实际文件,它们都接受一个 path 参数:
fs::exists(p); // 路径是否存在 |
需要注意的是,这些会真正访问文件系统的操作在出错时(例如路径不存在、权限不足)会抛出 std::filesystem::filesystem_error 异常。库为几乎每个此类函数都提供了一个接受 std::error_code& 的重载版本,用于以非异常的方式获取错误:
std::error_code ec; |
8.3 遍历目录
std::filesystem::directory_iterator 用于遍历一个目录下的直接条目,而 recursive_directory_iterator 则会递归地遍历整个目录树。两者都可以直接用于基于范围的 for 循环,迭代得到的元素是 directory_entry:
for (const auto& entry : fs::directory_iterator(dir)) { |
directory_entry 会缓存它所对应的文件状态,因此 entry.is_regular_file()、entry.file_size() 等成员函数往往比对其路径再次调用非成员函数更高效。
8.4 创建、复制与删除
库还提供了一组用于修改文件系统的操作:
fs::create_directories(p / "a" / "b"); // 递归创建目录(中间目录不存在时一并创建) |
8.5 一个完整的例子
下面的例子综合演示了上述操作。为了让示例自包含、可重复运行,我们在系统临时目录下创建一个专用的工作目录,并在结束时清理:
#include <filesystem> |
欧长坤 © 2016-2026 版权所有, 采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议许可,代码使用 MIT 协议开源。
如果你认为本书对你起到了帮助,可以资助作者。