您的位置:首页 >C++如何获取硬盘分区的详细挂载信息 _ filesystem库实战【实战】
发布于2026-04-28 阅读(0)
扫一扫,手机访问

答案是:不能。很多开发者会误以为std::filesystem::space()能提供完整的磁盘信息,其实它只负责一件事:返回指定路径所在文件系统的空间统计,也就是capacity、free和a vailable这三个数字。至于这个空间属于哪个分区、挂载点路径是什么、文件系统类型为何,它一概不告诉你。
这就好比问一个仓库管理员“库房里还有多少空位”,他能给你一个准确的数字,但你要问他“这个仓库在哪个园区、门牌号多少、用什么锁”,他就无能为力了。你传入"C:/"或"/home",它只会埋头计算该路径所在的文件系统空间,绝不会反过来告诉你对应的设备名或挂载配置。
既然标准库不提供,那就得用系统自己的方法。在Linux环境下,没有跨平台的通用接口,最直接可靠的方式就是去读取系统文件。这里有个关键区别:要获取当前实际生效的挂载信息,应该解析/proc/mounts,这是内核提供的实时视图;而不是去读/etc/fstab,那只是静态配置文件,里面的条目不一定都已经挂载上了。
具体怎么操作呢?
/proc/mounts的每一行都遵循固定格式:设备名、挂载点、文件系统类型、挂载选项、dump标志、pass标志,各字段之间用空格分隔。需要注意的是,挂载点路径和挂载选项字符串内部可能包含空格或特殊字符,解析时不能简单按空格切割,得根据字段数量进行容错处理。std::ifstream逐行读取,然后用std::istringstream进行分词。我们主要关心第2列(挂载点)、第3列(文件系统类型fstype)和第4列(挂载选项opts)。#开头的注释行。更重要的是,像rootfs、sysfs、proc这类伪文件系统并非实际的硬盘分区,通常需要将它们过滤掉,只保留物理磁盘或网络存储等条目。std::string line;
while (std::getline(fs, line)) {
if (line.empty() || line[0] == '#') continue;
std::istringstream iss(line);
std::string dev, mountpoint, fstype, opts;
if (iss >> dev >> mountpoint >> fstype >> opts) {
if (fstype != "rootfs" && fstype != "sysfs" && fstype != "proc") {
// 此时,mountpoint 和 fstype 就是我们需要的信息
}
}
}
Windows的哲学与Linux不同,它没有明确的“挂载点”概念,取而代之的是驱动器字母。不过,我们可以通过一组API组合来获取等效信息。
GetLogicalDrives()函数,它会返回一个位掩码(bitmask),每一位代表一个存在的驱动器字母(例如C:、D:)。遍历这个掩码就能得到所有有效的盘符。GetVolumeInformation(L"C:\\", ...)。这个函数能提供丰富的卷信息,包括卷标(lpVolumeNameBuffer)、文件系统名称(lpFileSystemNameBuffer,如“NTFS”、“FAT32”)、卷序列号等。这里有个细节要注意:传入的路径必须是带有尾部反斜杠的根路径(如L"C:\\"),否则调用会失败。另外,lpVolumeNameBuffer有可能为空字符串,这表示该卷没有设置卷标。GetVolumePathNamesForVolumeName()来查询某个卷的所有挂载路径。例如,一个NTFS卷可能同时被挂载到C:和D:\data。当你试图将这些逻辑封装成一个统一的接口时,注意力往往集中在获取路径和类型这些主要信息上。然而,下面这三个细节如果被忽略,你的程序在复杂的真实环境中很可能 silently fail(静默失效)。
立即学习“C++免费学习笔记(深入)”;
/proc/mounts中列出的挂载点,有可能是一个符号链接(例如/home → /mnt/data/home)。如果你直接用读到的字符串与用户传入的路径进行比较,可能会因为路径形式不一致而失败。稳妥的做法是,使用std::filesystem::canonical()函数将路径归一化,消除符号链接的影响。GetLogicalDrives()检测到的驱动器都是可立即访问的。例如,光驱里没有光盘,或者USB设备已被拔出,这些驱动器是“存在但不可用”的状态。在调用GetVolumeInformation()之前,应该先用GetDriveType()检查驱动器类型。通常我们只关心DRIVE_FIXED(固定硬盘)或DRIVE_REMOVABLE(可移动磁盘),而对于DRIVE_NO_ROOT_DIR(没有根目录)这类状态,直接跳过即可。/proc/mounts,但在某些安全加固过的系统(比如特定配置的容器环境或开启了严格SELinux策略的主机)下,访问可能会被屏蔽。在Windows上,获取大部分基础卷信息不需要管理员权限,但如果你想查询诸如BitLocker加密状态等高级属性,则可能需要提权。编写代码时要考虑这些边界情况,做好错误处理。说到底,真正的挑战从来不是“如何读取数据”,而是“如何确保读取到的数据在千变万化的运行环境中是可信的”。举个例子,/proc/mounts里有一行记录:/dev/sdb1 /mnt/usb vfat rw,nosuid...。你的程序不能假设这条记录一定有效。更严谨的做法是,在获取信息后,加一步简单的验证,比如调用std::filesystem::exists("/mnt/usb"),确认这个挂载点当前确实可访问,而不是一个已被卸载但残留的条目。这一步小小的检查,往往比复杂的逻辑更能保证程序的健壮性。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
9