c++ filesystem
来源:
http://www.modernescpp.com/index.php/c-17-more-details-about-the-library
https://www.bfilipek.com/2017/08/cpp17-details-filesystem.html
Filesystem 概览
c++ fielsystem 的模子是 boost的filesystem(2003年就出来了,为啥我不知道?);都是基于POSIX的。
三/四个核心部分:
- path object
- directory_entry
- Directory iterators
- Plus many supportive functions
- getting information about the path
- files manipulation: copy, move, create, symlinks
- last write time
- permissions
- space/filesize
- …
Working with the Path object
namespace fs = std::experimental::filesystem;
fs::path pathToShow("C:\\Windows\\system.ini");
cout << "exists() = " << fs::exists(pathToShow) << "\n"
<< "root_name() = " << pathToShow.root_name() << "\n"
<< "root_path() = " << pathToShow.root_path() << "\n"
<< "relative_path() = " << pathToShow.relative_path() << "\n"
<< "parent_path() = " << pathToShow.parent_path() << "\n"
<< "filename() = " << pathToShow.filename() << "\n"
<< "stem() = " << pathToShow.stem() << "\n"
<< "extension() = " << pathToShow.extension() << "\n";
输出如下:
exists() = 1
root_name() = C:
root_path() = C:
relative_path() = Windows\system.ini
parent_path() = C:\Windows
filename() = system.ini
stem() = system
extension() = .ini
What’s great about the above code?
用起来很方便,还可以跨平台,太爽了。
还可以遍历一个path:
int i = 0;
for (const auto& part : pathToShow)
cout << "path part: " << i++ << " = " << part << "\n";
输出:
path part: 0 = C:
path part: 1 =
path part: 2 = Windows
path part: 3 = system.ini
如何拼接path
两个办法: 用 operator /=, 或 operator +=.
/= - 添加一个文件夹
+= - 直接以字符串形式拼接到后面
fs::path p1("C:\\temp");
p1 /= "user";
p1 /= "data";
cout << p1 << "\n";
fs::path p2("C:\\temp\\");
p2 += "user";
p2 += "data";
cout << p2 << "\n";
输出:
C:\temp\user\data
C:\temp\userdata
获取文件大小
uintmax_t ComputeFileSize(const fs::path& pathToCheck)
{
if (fs::exists(pathToCheck) &&
fs::is_regular_file(pathToCheck))
{
auto err = std::error_code{};
auto filesize = fs::file_size(pathToCheck, err);
if (filesize != static_cast<uintmax_t>(-1))
return filesize;
}
return static_cast<uintmax_t>(-1);
}
获取最后修改时间
auto timeEntry = fs::last_write_time(entry);
time_t cftime = chrono::system_clock::to_time_t(timeEntry);
cout << std::asctime(std::localtime(&cftime));
额外说一下,以path为参数的函数大部分都有两个版本:
- 一个抛异常: filesystem_error
- 一个返回错误码: error_code (system specific)
遍历目录
两种遍历:
- directory_iterator(非递归遍历)
- recursive_directory_iterator - (递归遍历,遍历顺序未定义,每个文件或目录只遍历一次)
两种遍历都会忽略 '.' 和 '..'
void DisplayDirTree(const fs::path& pathToShow, int level)
{
if (fs::exists(pathToShow) && fs::is_directory(pathToShow))
{
auto lead = std::string(level * 3, ' ');
for (const auto& entry : fs::directory_iterator(pathToShow))
{
auto filename = entry.path().filename();
if (fs::is_directory(entry.status()))
{
cout << lead << "[+] " << filename << "\n";
DisplayDirTree(entry, level + 1);
cout << "\n";
}
else if (fs::is_regular_file(entry.status()))
DisplayFileInfo(entry, lead, filename);
else
cout << lead << " [?]" << filename << "\n";
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端