c++oding="utf-8" ?>
不可靠——std::filesystem::space仅返回路径所在文件系统的空间信息,无法枚举挂载点、识别设备名或区分bind mount,且不提供挂载点本身;跨平台获取df -h级信息需linux解析/proc/mounts+statvfs、windows调用卷api。

用 std::filesystem::space 获取分区剩余空间是否可靠?
不可靠——它只返回调用路径所在文件系统的空间信息,且不提供挂载点(mount point)本身。比如传入 "./" 或 "/home/user",得到的是该路径所在分区的 capacity/free/available,但你根本不知道这个分区挂载在哪儿、设备名是什么、是否是独立挂载(如 /boot、/home)、有没有被 bind mount 覆盖。
实际场景中,你要列出所有挂载点(如 /、/boot、/home),并分别查它们的剩余空间,std::filesystem::space 单独用解决不了这个问题。
-
std::filesystem::space是“路径到空间”的单向查询,不是“系统到挂载点”的枚举工具 - 它不区分
free(root 可用)和available(普通用户可用),而 Linuxstatvfs会返回f_bavail,更贴近df -h行为 - Windows 下它可能返回整个卷信息,但无法识别 NTFS 的挂载点(如
C:mntdisk2这种目录挂载)
Linux 下必须解析 /proc/mounts 或调用 getmntent
标准 C++ 没有跨平台挂载点枚举接口,Linux 必须依赖系统设施。/proc/mounts 是最轻量、无需链接额外库的方式,但要注意过滤伪文件系统(proc、sysfs、devtmpfs 等)和网络/内存文件系统(nfs、tmpfs),否则你会拿到一堆无效或不可用的空间数据。
推荐直接读取 /proc/mounts 并逐行解析,比调用 setmntent + getmntent 更可控(避免 glibc 版本兼容问题)。
- 每行格式为:
device_name mount_point fs_type options dump pass,用空格或 tab 分隔 - 关键过滤条件:
fs_type应为ext4、xfs、btrfs、vfat、ntfs3等物理存储类型;排除proc、sysfs、debugfs、securityfs、tmpfs、devtmpfs - 对每个通过过滤的
mount_point,再调用std::filesystem::space(mount_point)获取空间数据 - 注意:某些挂载点(如
/run)可能是tmpfs,但被误列入,务必按fs_type字段严格判断
Windows 下怎么拿到类似 df -h 的结果?
Windows 没有统一挂载点概念,但有卷(volume)和驱动器号(C:、D:),以及通过 MountVol 创建的目录挂载点。C++ 标准库完全无法枚举这些,必须用 Windows API。
核心是 GetLogicalDrives() + GetDiskFreeSpaceEx(),但它只能拿到驱动器号,拿不到目录挂载点(例如你把卷 \?Volume{...} 挂到了 C:data,这个映射关系不在 API 直接返回里)。
- 若只要驱动器号信息:遍历
A:到Z:,用GetDriveType()排除非固定磁盘(DRIVE_FIXED),再用GetDiskFreeSpaceEx()查空间 - 若要目录挂载点(如
C:mntol2):必须调用FindFirstVolume/FindNextVolume枚举卷 GUID,再对每个卷调用FindFirstVolumeMountPoint获取所有挂载路径 -
std::filesystem::space在 Windows 上对驱动器根路径("C:\")有效,但对挂载目录("C:\mnt\vol2")也有效——前提是该路径确实是一个卷挂载点;否则它会向上回溯到父卷,导致重复统计
跨平台封装时最容易踩的坑
别试图用 std::filesystem::space 加一个“找父挂载点”的逻辑来模拟 df——它没有提供底层 statvfs 或 GetDiskFreeSpaceEx 的原始字段,也没法告诉你当前路径是否就是挂载根(st_dev 对比),更没法处理 bind mount 或 overlayfs。
- Linux 下:不要信任
std::filesystem::current_path()所在位置代表“主分区”,/和/home很可能属于不同设备 - Windows 下:
GetDiskFreeSpaceEx返回的*lpFreeBytesAvailable是用户可用空间(类似f_bavail),而std::filesystem::space的available字段在 MSVC 实现中正是映射它,但 GCC/libstdc++ 在 MinGW 下行为不一致,慎用 - 权限问题:非 root 用户读
/proc/mounts没问题,但某些安全加固系统(如 Android SELinux)可能限制访问;Windows 上需要确保进程有查询卷信息的权限(通常默认有) - 符号链接路径:传给
std::filesystem::space前务必用std::filesystem::canonical()展开,否则可能查到错误设备
真正可靠的方案永远是:Linux 走 /proc/mounts + statvfs,Windows 走卷枚举 API,std::filesystem::space 只作最终空间查询的便携包装,绝不用于发现挂载结构。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











