std::filesystem::space() 是 c++17 获取磁盘剩余空间的标准跨平台方案,需传入根路径(如"c:/"或"/"),返回的 available 字段表示当前用户真正可用字节数,使用时须捕获 filesystem_error 异常。

用 std::filesystem::space() 获取磁盘剩余空间最直接
这是 C++17 引入的标准方案,无需第三方库或平台 API,跨 Windows/macOS/Linux 有效。调用前确保路径指向根目录(如 "C:/" 或 "/"),否则返回的是该路径所在文件系统的空间信息——不是当前工作目录的父目录,也不是某个子目录的“局部”空间。
关键点:
-
std::filesystem::space()返回std::filesystem::space_info结构体,含capacity、free、available三个字段 -
available是普通用户真正能写入的字节数(已扣除 root 预留空间、配额限制等),日常判断“还能存多少”应优先用它,而非free - 若路径不存在或无访问权限,会抛出
std::filesystem::filesystem_error,必须捕获
#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
<p>int main() {
try {
auto s = fs::space("C:/"); // Windows 示例
std::cout << "可用字节: " << s.available << "
";
} catch (const fs::filesystem_error& e) {
std::cerr << "获取空间失败: " << e.what() << "
";
}
}Windows 下用 GetDiskFreeSpaceEx() 更细粒度但不跨平台
当需要区分“总容量 / 总空闲 / 可用给当前用户”三者,且项目限定 Windows 时,Win32 API 的 GetDiskFreeSpaceEx() 比 std::filesystem::space() 多返回一个 lpTotalNumberOfFreeBytes(即 free 字段),而 std::filesystem::space() 的 free 和 available 在 Windows 上通常相等(除非启用了磁盘配额)。
注意:
立即学习“C++免费学习笔记(深入)”;
- 参数传入的是根路径字符串,结尾必须带
'\'(如"C:\\"),否则可能返回错误结果 - 返回值为
BOOL,失败时所有输出参数值未定义,不能直接用 - 需包含
<windows.h></windows.h>,且链接kernel32.lib(MSVC 默认链接)
#include <windows.h>
#include <iostream>
<p>int main() {
ULARGE_INTEGER free, total, total_free;
if (GetDiskFreeSpaceEx(L"C:", &free, &total, &total_free)) {
std::wcout << L"当前用户可用: " << free.QuadPart << L" 字节
";
std::wcout << L"总空闲(含预留): " << total_free.QuadPart << L" 字节
";
}
}
std::filesystem::space() 常见报错和绕过方法
最常遇到的是 filesystem error: cannot determine space allocation information,原因通常是:
- 路径格式错误:传了相对路径如
"./data",而它只认挂载点(根路径或驱动器根) - 权限不足:Linux/macOS 下对某些挂载点(如
/proc、/sys)无读权限;Windows 下对网络驱动器或加密卷可能受限 - 路径不存在:比如传了
"Z:/"但该驱动器未映射
安全做法是先用 fs::exists() 和 fs::is_directory() 校验路径有效性,再尝试 space();对不确定的路径(如用户输入),可 fallback 到当前工作目录所在设备:
try {
auto s = fs::space(fs::current_path()); // 保底:查当前目录所在文件系统
} catch (...) { /* 记录日志,返回 0 或 -1 表示未知 */ }单位换算与显示精度容易被忽略
std::filesystem::space_info 所有字段都是 uint64_t 字节,直接打印数字不友好。别用 KB/MB/GB 简单除 1024 —— 要区分二进制(KiB/MiB/GiB)还是十进制(KB/MB/GB)。用户界面推荐用二进制前缀(IEC 标准),例如:
- 1 KiB = 1024 B,1 MiB = 1024² B
- 显示时保留 1 位小数,但避免对 0.0 MiB,应降级到 KiB 或字节
- 不要用
std::round()对字节数四舍五入后再除——先做浮点除法再 round 显示值
实际中,很多程序在显示“剩余 2.3 GB”时,底层仍是字节运算,只是格式化逻辑没写对,导致用户看到的数值和资源管理器不一致。









