目录
一、std::filesystem 概述
1. 核心作用
2. 核心组件
二、std::filesystem 的基本用法
1. 路径操作(std::filesystem::path)
(1) 路径构造与拼接
(2) 路径分解
(3) 路径修改
2. 目录与文件操作
(1) 创建目录
(2) 删除目录
(3) 检查文件存在
(4) 查询文件属性
3. 目录遍历
(1) 非递归遍历
(2) 递归遍历
(3) 过滤条件
4. 文件与目录操作
(1) 复制文件或目录
(2) 移动文件或目录
三、错误处理机制
1. 异常处理
2. 基于错误码的处理
四、跨平台注意事项
1. 路径分隔符处理
示例:
2. 大小写敏感性
五、常见问题与解决方案
1. 路径拼接错误
问题:
解决方案:
2. 权限不足导致的操作失败
问题:
解决方案:
3. 递归遍历性能问题
问题:
解决方案:
六、示例代码汇总
示例 1:创建目录并检查文件大小
示例 2:递归删除目录
示例 3:遍历目录并统计文件数量
七、总结
1. std::filesystem 的核心优势
2. 适用场景
3. 最佳实践
C++从入门到入土学习导航_c++学习进程-CSDN博客
std::filesystem
概述std::filesystem
是 C++17 引入的标准化文件系统操作库,基于 Boost.Filesystem 的功能实现。它解决了以下问题:
\
分隔符)和 POSIX(使用 /
分隔符)系统的路径差异。std::filesystem::path
类封装路径操作,避免手动拼接字符串导致的错误。类/函数 | 功能描述 |
---|---|
std::filesystem::path |
表示文件路径,支持路径拼接、分解、检查等操作。 |
std::filesystem::directory_iterator |
遍历目录中的条目。 |
std::filesystem::recursive_directory_iterator |
递归遍历目录及其子目录。 |
std::filesystem::create_directory |
创建单个目录。 |
std::filesystem::remove |
删除文件或空目录。 |
std::filesystem::exists |
检查文件或目录是否存在。 |
std::filesystem::file_size |
查询文件大小。 |
std::filesystem::copy |
复制文件或目录。 |
std::filesystem
的基本用法std::filesystem::path
)#include
#include
namespace fs = std::filesystem;
int main() {
fs::path p1 = "C:/Users/Example"; // Windows 路径
fs::path p2 = "/home/user/documents"; // Linux 路径
fs::path p3 = p1 / "data" / "file.txt"; // 自动适配系统分隔符
std::cout << "Path: " << p3 << std::endl;
std::cout << "Native path: " << p3.native() << std::endl; // 显示系统原生格式
}
fs::path p = "C:/Users/Example/data/file.txt";
std::cout << "Root name: " << p.root_name() << std::endl; // C:
std::cout << "Root path: " << p.root_path() << std::endl; // C:/
std::cout << "Relative path: " << p.relative_path() << std::endl; // Users/Example/data/file.txt
std::cout << "Parent path: " << p.parent_path() << std::endl; // C:/Users/Example/data
std::cout << "Filename: " << p.filename() << std::endl; // file.txt
std::cout << "Stem: " << p.stem() << std::endl; // file
std::cout << "Extension: " << p.extension() << std::endl; // .txt
fs::path p = "C:/Users/Example/data/file.txt";
p.remove_filename(); // 移除文件名部分 → C:/Users/Example/data/
p.replace_extension(".bak"); // 修改后缀 → C:/Users/Example/data/file.bak
p.make_preferred(); // 转换为系统首选分隔符 → C:\Users\Example\data\file.bak (Windows)
fs::create_directory("new_dir"); // 创建单级目录(父目录必须存在)
fs::create_directories("nested_dir/sub_dir"); // 递归创建多级目录
fs::remove("empty_dir"); // 删除空目录
fs::remove_all("dir_with_files"); // 递归删除目录及内容
if (fs::exists("example.txt")) {
std::cout << "File exists!" << std::endl;
} else {
std::cout << "File not found." << std::endl;
}
if (fs::exists("example.txt")) {
std::cout << "File size: " << fs::file_size("example.txt") << " bytes" << std::endl;
std::cout << "Last modified time: " << fs::last_write_time("example.txt") << std::endl;
}
for (const auto& entry : fs::directory_iterator("C:/")) {
std::cout << "Entry: " << entry.path() << std::endl;
}
for (const auto& entry : fs::recursive_directory_iterator(".")) {
std::cout << "Recursive entry: " << entry.path() << std::endl;
}
for (const auto& entry : fs::directory_iterator(".")) {
if (entry.is_regular_file() && entry.path().extension() == ".cpp") {
std::cout << "C++ source file: " << entry.path() << std::endl;
}
}
fs::copy("source.txt", "destination.txt"); // 复制文件
fs::copy("source_dir", "destination_dir", fs::copy_options::recursive); // 递归复制目录
fs::rename("old_name.txt", "new_name.txt"); // 重命名文件
fs::rename("old_dir", "new_dir"); // 重命名目录
默认情况下,std::filesystem
会抛出 std::filesystem::filesystem_error
异常:
try {
fs::remove("nonexistent_file");
} catch (const fs::filesystem_error& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
通过传递 std::error_code
参数,避免异常抛出:
std::error_code ec;
fs::remove("nonexistent_file", ec);
if (ec) {
std::cerr << "Error: " << ec.message() << std::endl;
}
\
作为路径分隔符,但 std::filesystem::path
会自动将 /
转换为 \
。/
作为路径分隔符,std::filesystem::path
会保持原样。fs::path p1 = "C:/Users/Example"; // Windows 下自动转换为 C:\Users\Example
fs::path p2 = "/home/user/documents"; // Linux 下保持不变
手动拼接路径可能导致分隔符错误(如 C:/Users/Example\file.txt
)。
使用 std::filesystem::path
的 /
操作符自动适配分隔符。
尝试删除或修改受保护的文件或目录时抛出异常。
try-catch
捕获异常或检查错误码。recursive_directory_iterator
可能因大量文件导致性能下降。
#include
#include
namespace fs = std::filesystem;
int main() {
fs::path dir = "example_dir";
if (!fs::exists(dir)) {
fs::create_directory(dir);
std::cout << "Directory created: " << dir << std::endl;
}
fs::path file = dir / "example.txt";
std::ofstream(file) << "Hello, filesystem!"; // 写入内容
if (fs::exists(file)) {
std::cout << "File size: " << fs::file_size(file) << " bytes" << std::endl;
}
return 0;
}
#include
#include
namespace fs = std::filesystem;
int main() {
fs::path dir = "test_dir";
if (fs::exists(dir)) {
fs::remove_all(dir);
std::cout << "Directory removed: " << dir << std::endl;
} else {
std::cout << "Directory does not exist." << std::endl;
}
return 0;
}
#include
#include
namespace fs = std::filesystem;
int main() {
int file_count = 0;
for (const auto& entry : fs::recursive_directory_iterator(".")) {
if (entry.is_regular_file()) {
++file_count;
}
}
std::cout << "Total files: " << file_count << std::endl;
return 0;
}
std::filesystem
的核心优势path
类避免手动拼接路径错误。std::filesystem::path
:替代字符串拼接。通过掌握 std::filesystem
,开发者可以高效、安全地处理文件系统操作,构建跨平台且健壮的 C++ 应用程序。