std::filesystem::space 返回调用路径所在文件系统的空间信息,而非挂载点路径;它基于 statvfs 或 GetDiskFreeSpaceEx 获取该路径所属文件系统实例的容量、可用与空闲空间,不解析符号链接,也不提供挂载点位置。

std::filesystem::space 返回的是挂载点还是文件系统根?
std::filesystem::space 获取的不是“挂载点路径”,而是**调用路径所在文件系统的空间信息**——它底层调用的是 statvfs(Linux/macOS)或 GetDiskFreeSpaceEx(Windows),作用域是“该路径所属的文件系统实例”,和 mount point 无直接映射关系。比如你传入 "/home/user/docs/report.txt",它返回的是 /home 所在分区(可能是 /dev/sda2)的剩余空间,但不会告诉你这个分区挂在哪(/home 还是 /)。
常见错误现象:
– 误以为传入 "/mnt/usb" 就能拿到 U 盘的挂载点路径;
– 在符号链接路径上调用,结果返回的是目标文件系统而非链接所在位置的文件系统(std::filesystem::space 默认不解析 symlink)。
- 使用场景:适合快速判断“这个路径还能不能写入”,不适合枚举挂载点或获取挂载路径
- 若需挂载点路径,得配合
/proc/mounts(Linux)、getmntinfo(macOS)或GetVolumePathNamesForVolumeNameW(Windows) - 参数差异:
std::filesystem::space只接受一个std::filesystem::path,且要求路径存在、可访问;传入不存在路径会抛std::filesystem::filesystem_error
std::filesystem::space 在不同平台对根路径 "/" 的行为差异
Linux/macOS 下传入 "/" 通常返回 root 文件系统的空间;但 Windows 上 "C:" 和 "C:/" 行为一致,而 "C:"(无尾部斜杠)可能被解释为当前工作目录所在卷,导致结果不稳定。
性能 / 兼容性影响:
– 调用本身开销很小(一次系统调用),但频繁调用仍建议缓存(尤其在循环中检查磁盘余量时);
– C++17 标准要求实现支持此函数,但某些嵌入式或旧编译器(如 GCC stdc++fs)需手动链接 -lstdc++fs,否则链接失败报 undefined reference to 'std::filesystem::space'。
立即学习“C++免费学习笔记(深入)”;
- Windows 注意:驱动器号必须带冒号和反斜杠(
"C:\"),纯"C:"不可靠 - Linux 注意:传入
"/proc"或"/sys"这类虚拟文件系统路径,返回的capacity和free常为 0 或极大值(取决于内核实现),不可用于实际空间判断 - 安全起见,始终用
std::error_code重载版本:std::filesystem::space(p, ec),避免异常中断流程
如何从路径反推其挂载点(Linux 实用方案)
没有标准 C++ 接口能直接做到。Linux 下最稳妥的做法是读取 /proc/self/mountinfo,按路径最长前缀匹配找到对应挂载项,再提取第 5 字段(挂载点)。注意这不是 std::filesystem 的职责,属于系统级查询。
容易踩的坑:
– 用 /proc/mounts 替代 /proc/self/mountinfo:前者不包含挂载传播和绑定挂载细节,遇到 mount --bind 或容器环境容易误判;
– 忽略路径规范化:输入 "/home/../home/user" 必须先 std::filesystem::canonical 或 std::filesystem::weakly_canonical,否则匹配失败。
- 关键步骤:读取
/proc/self/mountinfo→ 每行分割 → 提取第 4 字段(挂载源,如/dev/sdb1)和第 5 字段(挂载点,如/mnt/data)→ 对目标路径向上逐级parent_path()匹配挂载点 - 示例片段逻辑:
std::filesystem::path target = std::filesystem::canonical("/mnt/data/logs/app.log"); while (!target.empty()) { if (mount_points.count(target)) return target; target = target.parent_path(); } - 不要依赖
df -P解析:子进程调用慢、有竞态、输出格式受 locale 影响(如千位分隔符)
std::filesystem::space 的返回值单位与精度陷阱
std::filesystem::space_info 中的 capacity、free、available 单位是字节,但它们是**文件系统块大小的整数倍**,并非精确到字节的可用空间。尤其 available 是普通用户可用空间(扣除了 root reserved blocks),而 free 是所有用户总空闲块(Linux ext4 默认保留 5% 给 root)。
典型误用:
– 用 free 判断程序能否写入 1GB 文件,结果因权限/预留空间失败;
– 把 available 当作“当前进程一定能写入的上限”,忽略了其他进程并发写入、quota 限制或 inodes 耗尽等非空间因素。
- 建议策略:优先用
available做预检(更贴近实际可用),但写入前仍需捕获std::filesystem::filesystem_error(错误码std::errc::no_space_on_device) - 大文件场景下,别只看字节数:ext4/inode 用尽时
space.available > 0但open()仍失败,需额外检查statvfs.f_files和f_ffree(这已超出std::filesystem::space能力) - 跨平台时,Windows NTFS 的
available和free通常相等(无 reserved space 概念),但压缩卷或配额开启时会有差异
std::filesystem::space 就不是那个工具——它设计目标很窄:给定路径,快速回答“这里大概还有多少空间”。越界使用,只会掉进系统抽象层的缝隙里。



















