std::filesystem::space() 不直接获取目录所在磁盘剩余空间,需先用 weakly_canonical() 获取根路径再调用;Windows 可用 GetDiskFreeSpaceEx() 更精确,Linux/macOS 应用 statvfs();注意 available 才是普通进程可用空间。
标准 std::filesystem 不提供直接获取磁盘剩余空间的接口,必须用 std::filesystem::space() —— 它返回的是挂载点(如 "C:/" 或 "/")所在文件系统的空间信息,不是某个目录所在分区的“实时”剩余空间。
std::filesystem::space() 返回值看起来不准?常见误解是传入任意路径(如 "./data")就能得到该目录所在磁盘的剩余空间。但实际行为取决于实现和操作系统:
std::filesystem::space("C:/some/path") 通常能正确返回 C 盘信息;/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"),它逐级向上找第一个存在的父目录;":/",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"; } }
GetDiskFreeSpaceEx() 更可靠?是的。当需要精确控制(如区分“可用给当前用户”还是“总空闲”)、绕过 std::filesystem 的路径解析不确定性,或兼容旧版 MSVC(std::filesystem 在 VS2017 前不完整),可直接调 Windows API:
GetDiskFreeSpaceEx() 返回三个值:lpFreeBytesAvailable(当前用户可用)、lpTotalNumberOfBytes、lpTotalNumberOfFreeBytes;L"C:\\"),需用 fs::path::c_str() 并转为 wchar_t*;statvfs(),不能硬写 Windows API。跨平台代码里混用系统 API 会让维护变重,除非你明确知道目标平台且有特殊需求(比如审计级磁盘报告),否则优先用 std::filesystem::space() + weakly_canonical().root_path() 组合。
真正容易被忽略的是:即使路径合法,space() 返回的 available 字段在某些文件系统(如 ext4 预留 5% 空间给 root)下会小于 free,而普通进程看到的“可用空间”其实是 available —— 写日志或上传前检查容量,必须用这个值,而不是 free。