应枚举A:–Z:盘符,先用GetDriveType筛选DRIVE_FIXED、DRIVE_REMOVABLE、DRIVE_REMOTE等可用类型,再对有效盘符调用GetDiskFreeSpaceEx获取精确容量,避免直接遍历导致卡顿或错误。

Windows 下用 GetDriveType + GetDiskFreeSpaceEx 枚举所有盘符
Windows 没有“分区列表”系统调用,得靠枚举可能的盘符(A:–Z:)再逐个探测。关键不是“列出分区”,而是“哪些盘符实际存在且可访问”。GetDriveType 能快速筛掉未就绪、网络驱动器或不存在的盘符;GetDiskFreeSpaceEx 则提供真实可用空间(比 GetDiskFreeSpace 更准,支持 >4GB 文件系统)。
常见错误是直接遍历 A:–Z: 却不检查 GetDriveType 返回值,导致对软驱、光驱或空插槽反复调用 GetDiskFreeSpaceEx,引发明显卡顿或权限错误(如访问被禁用的 U 盘)。
- 只对
DRIVE_FIXED(本地硬盘)、DRIVE_REMOVABLE(U 盘/SD 卡)、DRIVE_REMOTE(映射网络驱动器)调用GetDiskFreeSpaceEx - 跳过
DRIVE_NO_ROOT_DIR和DRIVE_UNKNOWN,它们大概率不可用 - 用宽字符函数(
GetDriveTypeW、GetDiskFreeSpaceExW),避免 ANSI 编码路径乱码
Linux/macOS 用 /proc/mounts 或 getmntent 获取挂载点
类 Unix 系统不暴露“物理分区”概念,而是通过挂载点(mount point)组织存储。最可靠方式是读取 /proc/mounts(Linux)或用 setmntent("/etc/mtab", "r")(兼容性更好),配合 getmntent 解析每行。注意:不要解析 df 命令输出——它依赖 locale、格式不稳定,且无法获取挂载选项细节。
容易踩的坑是忽略文件系统类型过滤。比如 devtmpfs、sysfs、proc 这些内存伪文件系统会出现在 /proc/mounts 中,但显然不是磁盘分区。应只保留 ext4、xfs、btrfs、apfs、hfs 等真实块设备文件系统。
立即学习“C++免费学习笔记(深入)”;
- 用
statvfs()替代statfs(),前者 POSIX 标准,字段含义更一致 -
statvfs的f_frsize是“基本块大小”,计算总空间时用f_blocks * f_frsize,别误用f_bsize - macOS 上
/proc不存在,必须走getmntent+statvfs组合
跨平台统一查询:C++17 std::filesystem::space 的局限与绕过
std::filesystem::space 看似完美,但它的输入是路径而非设备名,且行为依赖底层 OS 实现。在 Windows 上传入 "C:" 可能成功,但 "C:\\" 才是稳定写法;Linux 上若传 "/" 只返回根挂载点,无法得知 /home 是否独立分区。
更严重的是,它不提供“该路径对应哪个设备”信息,也没法枚举所有挂载点。所以它适合已知路径查空间,不适合“发现所有磁盘分区”。强行用它做枚举,结果不可靠:比如 Windows 上 "A:" 若无光盘插入,space 会抛 std::filesystem::filesystem_error;Linux 上对未挂载的设备节点(如 /dev/sdb1)调用会失败。
- 仅用于已确认存在的、可访问的挂载点路径(如
"/"、"C:\") - 务必用
try/catch捕获std::filesystem::filesystem_error - 不要用它替代
GetDriveType或getmntent—— 它不是发现工具,只是查询工具
注意设备名与挂载点的映射关系(尤其是 Linux LVM / RAID)
用户真正关心的常是“这块 SSD 上有哪些逻辑卷”,而不仅是“/dev/sda1 用了多少”。Linux 下需解析 /proc/partitions、/sys/block/*/slaves 或调用 lsblk -J(需解析 JSON),才能把 /dev/mapper/vg0-lv_root 关联到物理盘 /dev/sda。Windows 的 WMIC 或 WMI 查询(Win32_Volume 类)也能拿到卷 GUID 与物理磁盘号的映射。
这个层面的问题,标准 C++ 库完全不涉及。如果业务需要展示“某块 NVMe 盘上所有分区”,就必须引入平台特定 API 或外部命令。别试图用 statvfs 的 statfs.f_fsid 反推设备——它在不同内核版本含义不同,且无法跨文件系统比较。
多数应用其实不需要这层映射。先确认需求是否真要物理归属,还是只要“用户能看到的存储单元”——后者用前述挂载点或盘符方案已足够。强行深挖设备拓扑,反而让代码脆弱且难以测试。



















