基础介绍
c++17引入了std::filesystem库,这是一个强大的文件系统操作工具,可以获取文件和目录的各种信息(文件名称、后缀、类型、大小,遍历目录等)。其依赖的头文件:#include <filesystem>
利用std::filesystem可以实现如下功能:
- 创建路径
- 获取路径的文件名(包含后缀)
- 获取文件名(不包含后缀)
- 获取文件名的后缀
- 路径修改
- 路径拼接
- 检查文件是否存在
- 获取文件大小
- 获取文件的最后修改时间
- 判断是否为文件
- 判断是否为目录
- 创建、复制、删除、重命名、移动文件
- 遍历目录/递归方式遍历目录
- 创建、删除目录,获取当前路径
- 权限相关的操作
- 获取文件系统空间信息
基本使用方法
路径相关操作
#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
using namespace std;
void example()
{
//创建路径
fs::path p1 = "/home/user/documents/file.txt"; //linux或unix系统
fs::path p2 = "C:\\Users\\Documents\\file.txt";
//路径相关操作
cout <<p1.filename()<<endl; //file.txt
cout <<p1.extension()<<endl; //.txt
cout <<p1.stem()<<endl; //file
cout <<p1.parent_path()<<endl; ///home/user/documents
//路径修改
fs::path p3 = p1;
p3.replace_filename("file1.txt"); //替换文件名
p3.repalce_extension(".doc"); //替换后缀
//路径拼接
fs::path dir = "/home/user";
fs::path full = dir / "documents" /"file.txt";
}
文件相关操作
#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
using namespace std;
void file_operation()
{
fs::path file = "file.txt";
//判断文件是否存在
if(fs::exists(file))
{
//获取文件大小
uintmax_t size = fs::file_size(file);
//最后修改时间
auto ftime = fs::last_write_time(file);
//文件类型
cout <<fs::is_regular_file(file)<<endl;
//复制文件
fs::copy(file,"file_bak.txt", fs::copy_options::overwrite_existing);
//删除文件
fs::remove(file);
}
//创建文件,并向文件中写入'a'
std::ofstream(file).put('a');
//重命名文件
fs::rename(file, "new_name.txt");
}
目录操作
void directory_operations() {
fs::path dir = "test_dir";
// 创建目录
fs::create_directory(dir);
fs::create_directories("nested/dirs/here"); // 创建多级目录
// 遍历目录
for (const auto& entry : fs::directory_iterator(dir)) {
cout << entry.path() << '\n';
}
// 递归遍历目录
for (const auto& entry : fs::recursive_directory_iterator(dir)) {
cout << entry.path() << '\n';
}
// 获取当前路径
fs::path current = fs::current_path();
// 修改当前路径
fs::current_path(dir);
// 删除目录
fs::remove(dir); // 只能删除空目录
fs::remove_all(dir); // 递归删除目录及其内容
}
文件状态和权限
void file_status() {
fs::path p = "example.txt";
// 获取文件状态
fs::file_status status = fs::status(p);
// 检查文件类型
if (fs::is_regular_file(status)) { }
if (fs::is_directory(status)) { }
if (fs::is_symlink(status)) { }
// 权限检查
fs::perms permissions = status.permissions();
if ((permissions & fs::perms::owner_read) != fs::perms::none) {
cout << "文件可读\n";
}
// 修改权限
fs::permissions(p, fs::perms::owner_all,
fs::perm_options::add);
}
空间信息
void space_info() {
fs::path p = "/";
// 获取磁盘空间信息
fs::space_info si = fs::space(p);
cout << "总空间: " << si.capacity << '\n'
<< "可用空间: " << si.free << '\n'
<< "可用空间(当前用户): " << si.available << '\n';
}
思考:为什么要引入std::filesystem
在没有引入std::filesystem库之前,用户对于文件系统的相关操作只能采取两种形式:
- 使用各个系统独有的文件系统操作接口,例如windows操作系统的文件操作API和linux下的POSIX文件操作API
- 某些库或者开发框架如qt或者boost,这些库提供了一些文件操作操作的接口
上面的来2种方式,首先他们各自的接口名称,使用方法各不相同,每次使用新的都需要重新去适应学习,c++17提供了这个特性后,就能从语法上统一,在不同的平台上采用相同的接口;std::filesystem 的引入极大地简化了文件系统操作,提供了统一的跨平台接口,使得代码更加可维护和可移植。
使用建议:推荐使用std::filesystem进行文件操作。