std::filesystem::space() 返回 std::filesystem::space_info 结构体,含 capacity(总容量)、free(空闲字节)、available(当前进程实际可用字节数,已扣权限和预留空间);必须传入有效路径并捕获 filesystem_error 异常。

用 std::filesystem::space() 获取分区剩余空间最直接
标准库 std::filesystem(C++17 起)提供了跨平台的磁盘空间查询能力,std::filesystem::space() 是唯一需要调用的函数。它返回一个 std::filesystem::space_info 结构体,含三个关键字段:capacity(总字节)、free(空闲字节)、available(用户可用字节,已扣权限/预留空间)。注意:free ≠ available,尤其在 Linux 或启用了配额的系统上,available 才是真实可用值。
实操建议:
- 传入路径必须是**已存在的目录或文件**,不能是空字符串或非法路径,否则抛
std::filesystem::filesystem_error - 路径应指向目标分区的某个挂载点(如 Windows 的
"C:/"、Linux 的"/home"),而非任意子路径——同一分区下任意有效路径返回结果相同 - 若需获取当前工作目录所在分区,可传
std::filesystem::current_path() - Windows 下路径分隔符用正斜杠
"/"或双反斜杠"\"均可,但单反斜杠""会触发转义错误
Windows 下获取 C 盘剩余空间的典型写法
常见错误是硬编码 "C:" 却未正确转义,或忽略异常处理导致程序崩溃。以下为安全写法:
#include <filesystem>
#include <iostream>
int main() {
try {
auto s = std::filesystem::space("C:/"); // 推荐用正斜杠,简洁无歧义
std::cout << "可用字节: " << s.available << "
";
std::cout << "空闲字节: " << s.free << "
";
std::cout << "总字节: " << s.capacity << "
";
} catch (const std::filesystem::filesystem_error& e) {
std::cerr << "获取空间失败: " << e.what() << "
";
}
}
关键点:
立即学习“C++免费学习笔记(深入)”;
- 用
"C:/"而非"C:"或"C:"—— 后者在某些实现中可能被解释为相对路径,行为不一致 - 必须捕获
std::filesystem::filesystem_error,例如路径不存在、无权限访问、驱动器未就绪(如光驱无盘)都会触发该异常 - 不要依赖
s.free显示“剩余空间”,它包含 root 预留空间;面向用户展示请用s.available
Linux/macOS 下获取根分区或 home 分区空间
Linux 和 macOS 行为一致,但要注意挂载点概念。例如 "/" 对应根分区,"/home" 可能是独立分区。若误传 "/nonexistent",会因路径不存在而抛异常;若传 "/tmp"(常为 tmpfs 内存文件系统),space() 返回的是内存虚拟空间,不是硬盘。
实操建议:
- 确认目标路径确属硬盘分区:可通过
df -T /path(Linux/macOS)验证文件系统类型是否为ext4、xfs、apfs等物理存储类型 - 避免传符号链接路径——
space()会解析到目标实际挂载点,可能不是你预期的分区 - 权限问题更常见:普通用户无法读取某些系统路径(如
/boot),此时异常信息通常含Permission denied - 若需遍历所有挂载点,C++ 标准库不提供接口,需调用系统命令(如
popen("df -P | awk 'NR>1 {print $6}'", "r"))或使用平台 API(statvfs)
单位换算与精度陷阱
std::filesystem::space_info 所有字段都是 uintmax_t 类型的字节数,直接输出数字对用户不友好。但简单除以 1024 或 1000 容易出错:
- 行业惯例是二进制前缀(KiB/MiB/GiB):1 KiB = 1024 字节,1 MiB = 1024² 字节
- 别用
float或double做大数除法——64 位整数(如 2TB ≈ 2×10¹² 字节)转 float 会丢失精度,显示为1.99999e+12这类近似值 - 推荐用整数运算 + 余数判断:先除以 1024³ 得 GiB,再对余数除以 1024² 得 MiB,依此类推
- 注意
available可能为 0(磁盘满或配额耗尽),需单独判断避免除零或负数显示
真正麻烦的从来不是调用哪个函数,而是搞清你要的到底是「磁盘空闲总量」还是「当前用户还能写多少」,以及路径是否真落在目标物理设备上——这两个点没踩准,后面所有计算都白搭。


















