目录文件操作
例子 目标路径存在性及类型
为什么要把文件称为“常规文件”(regular file)?
硬盘驱动器上几乎所有我们熟悉的文件 —— 文档、图像、可执行文件等,都被视为常规文件(regular files)。
除了目录和常规文件之外,我们的文件系统中还可以存在其他一些东西,例如块文件(block files)和符号链接(symbolic links)。
例子 获取文件属性如大小、最后修改时间
例子 创建目录
创建一个目录,mkdir path
抛出异常的情况
错误代码的含义取决于程序运行的操作系统。对于Windows系统,错误代码的含义可以看这里:Tutorial - Debug system error codes - Win32 apps | Microsoft Learn
创建目录,递归创建所有目录层级,mkdir -p path
注意这里用的是create_directories()
,不是create_directory()
。
例子 复制文件
如果copy_file()
第二个参数指定的路径已经存在,怎么办?可以为copy_file()
指定第三个参数,指示遇到这种情况如何处理。
是一个枚举,包含的值有:
- 保留现有文件并抛出异常(默认)
- 保留现有文件但不引发异常
- 覆盖现有文件
- 如果现有文件比新文件旧(按照),则覆盖现有文件
例子 复制目录
这里使用的是copy()
,上面使用的是copy_file()
。
copy()
不仅可以复制目录,也可以复制文件,但复制文件最好是用copy_file()
,不仅让我们的意图更清晰,而且copy_file()
具有内置的错误检查功能,以确保目标确实是一个文件。
可以传递的比较有用的附加选项有:
recursive
递归复制子目录
directories_only
只复制目录结构 - 忽略文件
可以用|
运算符来组合多个选项。
例子 删除文件
当参数是不为空的目录时,会抛出异常:
例子 删除目录
当我们想删除一个目录,并且想删除其中的所有内容时,可以使用 remove_all()
。它返回一个整数,表示删除了多少文件和目录。
返回值是一个整数,类型为uintmax_t
,一个固定的整数,可以像任何其他整数类型一样使用。
例子 移动和重命名文件或目录
可以使用 rename()
函数移动或重命名文件或目录。
第一个参数是要移动的条目的位置(路径)。第二个参数是想要将其移动到的位置。
例子 获取磁盘空间
space()
返回一个 space_info
结构,该结构具有下面三个数据成员,所有三个值均以字节(bytes)为单位:
capacity
- 该位置的可用总容量
free
- 该位置的可用空间容量
available
- 可供程序写入的空间容量。这将小于或等于 free
路径操作
例子 路径对象和字符串互转
例子 获取路径的特定部分
例子 判断路径的特定部分是否存在
.filename()
用于获取文件名,与之对应的.has_filename()
返回一个布尔值用于判断文件名是否存在。其他的函数也类似,在前面加has_
就变为了与之等同的布尔函数。
例子 路径文件名部分的操作
例子 路径拼接
例子 判断是绝对路径还是相对路径
例子 更改当前路径(current path)或者说当前工作目录(current working directory)
目录迭代器
例子 遍历某目录内所有条目,使用迭代器
例子 遍历某目录内所有条目,使用范围
配合std::ranges::for_each()
使用,不用显式构建subrange
:
输出:
例子 遍历目录内的所有条目,包括各级子目录内的所有条目
默认情况下,directory_iterator
仅迭代目录中的第一级条目。如果条目是子目录,不会深入进去迭代它里面的条目。
可以通过在 is_directory()
返回 true 时使用递归来自己实现此逻辑。不过标准库已经为我们提供了recursive_directory_iterator
。
下面的代码与前面相同,只是把directory_iterator
改为了recursive_directory_iterator
:
可以用recursive_directory_iterator
的depth()
成员函数来访问当前的递归深度(当前条目嵌套了多少层):
输出:
参考