文件系统库
这个新增的功能让我们能够与系统中的目录和文件进行交互。
新的 filesystem 库 基于 boost::filesystem。该库的部分组件是可选的,这意味着 std::filesystem 的所有功能并非在每个 filesystem 库的实现中都可用。例如,FAT-32 文件系统不支持符号链接。
ℹ️ 使用 cppreference.com
本书编写时(2017年10月),我手头没有支持新 filesystem 库的 C++ 编译器;因此,本章中的程序是在 cppreference.com: filesystem 上使用最新的 GCC 编译器运行的,该编译器支持新的 filesystem 库。要使用新的 filesystem 库,你可能需要包含实验性头文件并使用实验性命名空间。
1#include <experimental/filesystem> 2namespace fs = std::experimental::filesystem;本章所有示例均未使用实验性命名空间。
该库基于三个核心概念:文件、文件名和路径。
-
文件 是用于存储数据的对象,可以对其进行读写操作。每个文件都有一个名称和文件类型。文件类型包括目录、硬链接、符号链接和普通文件。
-
目录 是用于存放其他文件的容器。当前目录用单个点
"."表示,父目录用两个点".."表示。 -
硬链接 将一个名称与已存在的文件关联。
-
符号链接 将一个名称与某个路径关联,该路径可能指向一个尚不存在的目标。
-
普通文件 是既不是目录、硬链接也不是符号链接的目录项。
-
-
文件名 是表示文件的字符串。允许使用的字符、最大长度以及是否区分大小写由具体实现定义。
-
路径 是一系列用于标识文件位置的条目。它可包含可选的根名称(如 Windows 中的 "C:")和根目录(如 Unix 中的 "/")。后续部分可以是目录、硬链接、符号链接或普通文件。路径可分为绝对路径、规范路径和相对路径。
-
绝对路径 是能够唯一标识某个文件的完整路径。
-
规范路径 是不包含符号链接,也不包含
"."(当前目录)或".."(父目录)等相对路径成分的路径。 -
相对路径 是相对于文件系统中某一位置的路径。像
"."(当前目录)、".."(父目录)或"home/rainer"这样的路径都是相对路径。在 Unix 系统中,它们不以根目录"/"开头。
-
以下是 filesystem 库的一个入门示例:
1#include <fstream> 2#include <iostream> 3#include <string> 4#include <filesystem> 5namespace fs = std::filesystem; 6 7int main(){ 8 9 std::cout << "Current path: " << fs::current_path() << std::endl; 10 11 std::string dir= "sandbox/a/b"; 12 fs::create_directories(dir); 13 14 std::ofstream("sandbox/file1.txt"); 15 fs::path symPath= fs::current_path() /= "sandbox"; 16 symPath /= "syma"; 17 fs::create_symlink("a", symPath); 18 19 std::cout << "fs::is_directory(dir): " << fs::is_directory(dir) << std::endl; 20 std::cout << "fs::exists(symPath): " << fs::exists(symPath) << std::endl; 21 std::cout << "fs::symlink(symPath): " << fs::is_symlink(symPath) << std::endl; 22 23 24 for(auto& p: fs::recursive_directory_iterator("sandbox")) 25 std::cout << p << std::endl; 26 fs::remove_all("sandbox"); 27 28}
fs::current_path() (1) 返回当前工作路径。使用 std::filesystem::create_directories 可创建多级目录 (2)。/= 操作符针对路径进行了重载 (3),因此可以直接构建路径。接着可以创建符号链接 (4),或检查文件属性。调用 recursive_directory_iterator (5) 可递归遍历目录结构。
