C++ 17 filesystem
C++ 17 filesystem
filesystem 提供对路径、常规文件和目录的操作的库。有了该库,对于文件和目录的操作变得更加容易。
库相关的几个定义
file: 存放数据的文件系统对象,可读可写。拥有文件名字和属性。directory: 文件目录hard link: 硬链接symbolic link: 符号链接regular file: 常规文件
file name: 文件的名字,通常为一个字符串pathabsolute path: 绝对路径canonical path: 规范路径(不包含符号链接,.和..的路径)relative path: 相对路径(一个路径相对于另一个路径的路径,字符串中可能包含.和..)
Path 类及其相关内容
路径的定义
文件系统中对于路径名的定义包括以下几个部分
path name syntaxroot-name: 根的名字,例如C:或//myserverroot-directory: 根目录,将该路径标记为绝对路径的目录分隔符。file-name: 文件名directory-separator: 目录分隔符
path 类有一个常成员变量 constexpr value_type preferred_separator。在 windows 系统中为 \,在 POSIX 中为 /。
路径规范化算法
path 可以通过以下算法进行规范化:
- 如果路径为空,则停止;
- 替换连续的多个目录分隔符为单独的一个
preferred_separator,eg:/usr///////lib->/usr/lib - 替换
root-name中的每个斜杠字符为prefered_separator - 移除紧跟斜杠字符后的
.符号 - 移除紧跟斜杠字符后的
..符号,并将..前的非..文件名去掉,eg:/usr/local/include/../opencv2->/usr/local/include/opencv2 - 如果存在根目录,删除所有
..和紧随其后的所有目录分隔符 - 如果最后一个文件名是
..,删除所有结尾的目录分隔符 - 如果路径为空,则添加
.
路径的格式
路径有两种格式,native_format 和 generate_format。对于 POSIX-like 的文件系统,这两种格式是相同的。对于 Windows 文件系统,则是不同的。
- generic format 路径格式:
/home/mypc/myfile.txt - native format 路径格式(windows):
F:\\MyDirectory\\myFile.txt或F:\MyDirectory\myFile.txt
路径的操作
(constructor)&(destructor)&operator=&assign- 路径有构造函数和析构函数,可以通过
operator=进行赋值,也可以使用assign进行赋值。
- 路径有构造函数和析构函数,可以通过
append&operator/=&concat&operator+=- 路径有两个连接操作,
operator/=和append可以将两个路径进行连接,同时会添加一个分隔符。operator+=和concat也可以将两个路径进行连接,但是不会添加分隔符。
namespace fs = std::filesystem;
int main()
{
fs::path p1 = "/a/b/c/d";
fs::path p2 = "/e/f/g/h";
p1 /= "m";
std::cout << p1.generic_string() << std::endl; // /a/b/c/d/m
p1.append("n");
std::cout << p1.generic_string() << std::endl; // /a/b/c/d/m/n
p2 += "x";
std::cout << p2.generic_string() << std::endl; // /e/f/g/hx
p2.concat("y");
std::cout << p2.generic_string() << std::endl; // /e/f/g/hxy
return 0;
}- 路径有两个连接操作,
clear: 清除路径中的内容swap: 交换两个路径中的内容make_preferred: 将路径中的分隔符替换为preferred_separatorremove_filename: 将路径中的文件名去掉,具体是指删除最后一个文件分隔符之后的内容
namespace fs = std::filesystem;
int main()
{
fs::path p1 = "/a/b/c/d";
std::cout << p1.remove_filename() << '\n'; // /a/b/c
return 0;
}replace_filename: 替换路径中的最后一部分为其他路径replace_extension: 替换文件后缀c_str&native&operator string_type- 将路径转换为字符串
string&wstring&u8string&u16string&u32string- 根据具体的编码将路径转换为具体的 native 字符串格式
generic_string&generic_wstring&generic_u8string&generic_u16string&generic_u32string- 根据具体的编码将路径转换为具体的 generic 字符串格式
compare: 比较两个路径lexically_normal: 转换路径为 normal 格式(不包含.和..)lexically_relative: 转换路径为 relative 格式lexically_proximate: 转换路径为 proximate 格式empty: 检测路径是否为空is_absolute: 检查路径是否为绝对路径is_relative: 检查路径是否为相对路径begin: begin 迭代器end: end 迭代器- 迭代器所指向的序列包括:
root-nameroot-directory- sequence of
file-name(不包括分隔符) - 如果路径最后是分隔符,则序列的最后一个为空字符串
namespace fs = std::filesystem;
int main() {
fs::path p = R"(C:\Users\yangshun\AppData\Local\Temp\)";
for (auto it = p.begin(); it != p.end(); it++)
{
std::cout << *it << '\n';
}
for (auto & e : p)
{
std::cout << e << '\n';
}
return 0;
}
// Output:
// "C:"
// "\\"
// "Users"
// "yangshun"
// "AppData"
// "Local"
// "Temp"
// ""- 迭代器所指向的序列包括:
获取以及检查路径的几个部分
| 获取函数 | 检查函数 | 描述 |
|---|---|---|
root_name |
has_root_name |
获取(检查)路径根的名字 |
root_directory |
has_root_directory |
获取(检查)路径根目录(绝对路径的目录分隔符) |
root_path |
has_rootpath |
获取(检查)根路径,root_name + root_directory |
relative_path |
has_relative_path |
获取(检查)相对路径,除去 root_path 之后剩余的部分 |
parent_path |
has_parent_path |
获取(检查)除去文件名外的路径部分 |
filename |
has_filename |
获取(检查)文件名 |
stem |
has_stem |
获取(检查)文件名称 |
extension |
has_extension |
获取(检查)文件扩展 |
|
filesystem_error 类
filesystem_error 类是在对文件系统进行操作出现异常是抛出的错误,其成员变量包括 (constructor), operator=, path1, path2 和 what。path1 和 path2 是造成异常的路径。
directory_entry 类
directory_entry 代表目录条目。其对象会存储一个路径以及额外的一些文件属性(hard link count, status, symlink status file size, and last write time)
(constructor)&(destructor)&operator=&assignreplace_filename: 更改目录条目的文件名refresh: 刷新文件系统对象的属性状态path: 返回目录条目引用的完整路径exists: 检查目录条目是否存在is_block_file: 检查目录条目是否为块设备is_character_file: 检查目录条目是否为字符设备is_directory: 检查目录条目是否为目录is_fifo: 检查目录条目是否为命名管道is_other: 检查目录条目是否为其他文件is_regular_file: 检查目录条目是否引用常规文件is_socket: 检查目录条目是否引用常规文件is_symlink: 检查目录条目是否引用符号链接file_size: 返回目录条目引用的文件的大小hard_link_count: 返回引用目录条目所引用文件的硬链接数last_write_time: 获取或设置目录条目所引用文件的最后一次数据修改的时间status&symlink_status: 目录条目指定的文件的状态
directory_iterator 类
- 指向 directory_entry 中元素的迭代器,类型为输入迭代器。该迭代器不会遍历子文件夹。
recursive_directory_iterator 类
- 指向 directory_entry 中元素的迭代器,类型为输入迭代器。该迭代器会遍历所有子文件夹。除了迭代器通有的操作外,该迭代器还包括以下函数
depth: 返回当前递归的深度recursion_pending: 检查是否对当前目录禁用了递归pop: 在目录层次结构中将迭代器上移一级disable_recuresion_pending: 禁用递归,直到下一个增量
file_status 类
file_status 类存储了文件的类型和权限信息,type 函数可以获取或设置文件类型(返回 file_type 枚举类),permissions 函数可以获取或设置文件的权限(返回 perms 类)
space_info 结构体
表示由空间确定的文件系统信息。包括 capcity, free 和 available.
file_type 枚举类
type:file_typenonenot_foundregulardirectorysymlinkblockcharacterfifosocket
perms 枚举类
permissions:permsnoneowner_readowner_writeowner_execowner_allgroup_readgroup_writegroup_execgroup_allothers_readothers_writeothers_execothers_allallset_uidset_gidsticky_bitmask
perm_options 枚举类
perm_optionsreplaceaddremovenofollow
copy_options 枚举类
noneskip_existing: Keep the existing file, without reporting an error.overwrite_existing: Replace the existing fileupdate_existing: Replace the existing file only if it is older than the file being copiedrecursive: Recursively copy subdirectories and their contentcopy_symlinks: Copy symlinks as symlinks, not as the files they point toskip_symlinks: Ignore symlinksdirectories_only: Copy the directory structure, but do not copy any non-directory filescreate_symlinks: Instead of creating copies of files, create symlinks pointing to the originalscreate_hard_links: Instead of creating copies of files, create hardlinks that resolve to the same files as the originals
函数
absolute: 获取绝对路径canonical: 获取典型路径格式,会去掉.和..relative: 获取相对路径,默认为相对于当前路径的路径copy: 拷贝文件或者目录copy_file: 拷贝文件内容copy_symlinks: 拷贝符号链接create_directory: 创建目录create_hard_link: 创建硬链接create_symlink&create_directory_symlink: 创建符号链接current_path: 当前目录exists: 检查路径是否存在equivalent: 检查两个路径是否相等file_size: 获取文件的大小hard_link_count: 获取硬链接的数量last_write_time: 获取或者设置数据修改的最后时间permissions: 修改文件权限read_symlink: 获取符号链接的目标remove: 删除一个文件或者空目录remove_all: 删除一个文件或者递归删除一个文件目录rename: 移动或者重命名文件或者目录resize_file: 通过截断或者补零的方式改变常规文件的大小space: 确定文件系统上的可用空间status: 获取文件属性symlink_status: 获取文件属性,检查符号链接目标temp_directory_path: 获取临时目录路径
