std::filesystem::space() 不直接获取目录所在磁盘剩余空间,需先用 weakly_canonical() 获取根路径再调用;Windows 可用 GetDiskFreeSpaceEx() 更精确,Linux/macOS 应用 statvfs();注意 available 才是普通进程可用空间。

标准 std::filesystem 不提供直接获取磁盘剩余空间的接口,必须用 std::filesystem::space() —— 它返回的是挂载点(如 "C:/" 或 "/")所在文件系统的空间信息,不是某个目录所在分区的“实时”剩余空间。
为什么 std::filesystem::space() 返回值看起来不准?
常见误解是传入任意路径(如 "./data")就能得到该目录所在磁盘的剩余空间。但实际行为取决于实现和操作系统:
- 在 Windows 上,
std::filesystem::space("C:/some/path")通常能正确返回 C 盘信息; - 在 Linux/macOS 上,若路径跨挂载点(比如
/home是独立分区),传入"/home/user/project"可能返回/home分区信息 —— 但前提是底层statvfs()调用成功且路径有效; - 如果路径不存在、无权限、或指向符号链接末端失败,
space()会抛出std::filesystem::filesystem_error。
正确获取指定路径所在文件系统剩余空间的步骤
关键:先用 std::filesystem::canonical() 或 std::filesystem::weakly_canonical() 解析路径到真实挂载点根目录,再调用 space():
-
std::filesystem::canonical(path)要求路径存在,否则抛异常; -
std::filesystem::weakly_canonical(path)更安全,能处理不存在的子路径(如"D:/missing/dir"),它逐级向上找第一个存在的父目录; - 拿到规范化路径后,需提取其所在文件系统的根(Windows 是驱动器号 +
":/",Linux/macOS 是挂载点如"/"或"/home"); - 最稳妥方式是用
std::filesystem::path::root_path()获取根路径,再对根调用space()。
include#include namespace fs = std::filesystem; int main() { try { fs::path p = "C:/temp"; // 或 "/tmp" auto root = fs::weakly_canonical(p).root_path(); auto space_info = fs::space(root); std::cout << "Total: " << space_info.capacity << " bytes\n"; std::cout << "Free: " << space_info.free << " bytes\n"; std::cout << "Available: " << space_info.available << " bytes\n"; } catch (const fs::filesystem_error& e) { std::cerr << "Error: " << e.what() << "\n"; } }
Windows 下用 GetDiskFreeSpaceEx() 更可靠?
是的。当需要精确控制(如区分“可用给当前用户”还是“总空闲”)、绕过 std::filesystem 的路径解析不确定性,或兼容旧版 MSVC(std::filesystem 在 VS2017 前不完整),可直接调 Windows API:
立即学习“C++免费学习笔记(深入)”;
-
GetDiskFreeSpaceEx()返回三个值:lpFreeBytesAvailable(当前用户可用)、lpTotalNumberOfBytes、lpTotalNumberOfFreeBytes; - 注意参数是宽字符路径(
L"C:\\"),需用fs::path::c_str()并转为wchar_t*; - Linux/macOS 则应改用
statvfs(),不能硬写 Windows API。
跨平台代码里混用系统 API 会让维护变重,除非你明确知道目标平台且有特殊需求(比如审计级磁盘报告),否则优先用 std::filesystem::space() + weakly_canonical().root_path() 组合。
真正容易被忽略的是:即使路径合法,space() 返回的 available 字段在某些文件系统(如 ext4 预留 5% 空间给 root)下会小于 free,而普通进程看到的“可用空间”其实是 available —— 写日志或上传前检查容量,必须用这个值,而不是 free。











