概览
我经常需要文件系统功能,主要是 fs::path 和目录访问。使用 C++11 时,我利用语言更新尝试减少第三方依赖,成功淘汰了大部分原先使用的库,但仍缺少一些功能,于是开始将它们实现为个人项目。
最初,我根据自己的编码风格和命名约定构建了这些辅助工具。C++17 标准最终确定后,我希望采用其接口,但花了一些时间才重构自己的类以符合标准。
该实现与 C++17 标准的第 30.10 章紧密对齐,主要参考工作草案 N4687。虽然发布晚于 C++17 标准,但相较于工作草案 N4659,它包含了最新的文件系统接口更新。从 1.4.0 版本起,在 C++20 编译下,它会适配路径排序顺序和 std::u8string 处理的相关变化(参照工作草案 N4860)。
我感谢所有推动 C++ 发展的贡献者,非常欣赏 C++11 及后续标准带来的语言进步。你们的工作非常出色!
Kumo 文件系统
kumo 文件系统在 API 层基于 C++17 标准实现,但并不完全相同。考虑到 kumo 生态规范,实现有以下差异:
- 命名约定:
kumo生态类采用 CamelCase,函数采用 snake_case; - 返回值与异常处理:Kumo 文件系统函数功能与
std::filesystem等效,但返回值和参数有所不同;所有错误均通过turbo::Status或turbo::Result<T>返回,不抛异常; std::error_code参数一致性:接受std::error_code参数的函数在行为上与std::filesystem保持一致。
GHC Filesystem
该库兼容标准 C++ 文件系统接口(std::filesystem),完全遵循 C++17 标准的 API 设计,同时提供 header-only 实现,无需额外编译或链接库即可直接使用。适合希望保持跨平台兼容性、减少第三方依赖的场景。
你可以在不修改现有代码的前提下,用它替代 std::filesystem,几乎所有 C++17 文件系统操作都可以直接使用,包括路径处理、文件状态查询、目录遍历等。
示例代码
#include <ghc/filesystem.hpp> // header-only
#include <iostream>
namespace fs = ghc::filesystem;
int main() {
fs::path base_path("/home/user/docs");
fs::path file_path = base_path / "report.pdf";
// 输出完整路径
std::cout << "Full path: " << file_path << std::endl;
// 获取父目录和文件名
std::cout << "Parent directory: " << file_path.parent_path() << std::endl;
std::cout << "File name: " << file_path.filename() << std::endl;
// 文件是否存在
if (fs::exists(file_path)) {
std::cout << file_path << " exists" << std::endl;
} else {
std::cout << file_path << " does not exist" << std::endl;
}
// 遍历目录
for (auto& entry : fs::directory_iterator(base_path)) {
std::cout << "Entry: " << entry.path() << std::endl;
}
return 0;
}
特性总结
- 兼容性:完全兼容
std::filesystemAPI。 - Header-only:无需额外编译或链接库。
- 跨平台:支持 Windows、Linux、macOS。
- 完整功能:路径操作、文件状态查询、目录遍历、文件操作(创建、删除、复制、重命名)均支持。
Kumo File System vs Standard C++ Filesystem
Kumo 的文件系统实现基于 C++17 标准接口层,但并不完全等同于 std::filesystem。在 Kumo 生态中:
- 类名使用 CamelCase,函数名使用 snake_case;
- 提供的功能与
std::filesystem等效,但所有错误均通过turbo::Status/turbo::Result<T>返回,不抛异常; - 支持
std::error_code参数的接口与标准库一致。
此外,Kumo 文件系统库还兼容 ghc::filesystem 这一 header-only 的标准 C++ 文件系统实现,可在需要时提供标准接口。
为什么不直接使用标准库 std::filesystem?
主要是 兼容性问题。不同平台和编译器对标准文件系统的实现细节存在差异,如果直接依赖标准库,就需要在 Kumo 底层做大量适配工作。而 Kumo 只需要一套“够用、可控”的文件系统接口,能够统一错误处理和跨平台行为,无需折腾底层细节。因此,选择自研库既简单又高效,同时也保证了 Kumo 系统的稳定性和可维护性。