Windows下最可靠方式是通过WMI查询MSFT_PhysicalDisk的MediaType字段:先将路径映射为卷,再关联到物理磁盘,MediaType值为3(SSD)或4(NVMe)即确认为固态硬盘,需配合COM初始化及安全上下文设置。

Windows 下通过 WMI 查询磁盘类型
直接判断某个路径所在的磁盘是不是 SSD,在 C++ 里没有标准 API,得靠系统级接口。Windows 最可靠的方式是用 WMI(Windows Management Instrumentation)查 MSFT_PhysicalDisk,再把路径映射到驱动器号,最后比对 MediaType 字段。
常见错误是只查 Win32_DiskDrive,它返回的是物理设备,但一个 SSD 可能被分成多个卷,而路径可能落在某个 NTFS 卷上——必须先做路径 → 卷 → 物理磁盘的链路解析。
- 用
GetVolumePathName()把路径转成卷路径(如C:\) - 用
GetVolumeInformationByHandleW()或 WMI 的Win32_Volume查该卷对应的DeviceID(形如\?Volume{...}) - 再用 WMI 查询
MSFT_StorageSetting或关联MSFT_PhysicalDisk,检查MediaType是否等于3(SSD)或4(NVMe) - 注意:WMI 查询需启用 COM 初始化、设置安全上下文,否则
CoInitializeEx()和CoSetProxyBlanket()缺一不可
Linux 下读取 sysfs 中的 rotational 标志
Linux 没有统一“SSD”标识,但内核通过 /sys/block/*/queue/rotational 文件提供间接判断:值为 0 表示非旋转介质(大概率是 SSD/NVMe),1 表示 HDD。
关键难点在于路径到设备名的映射。不能直接从 /dev/sda 推导,因为路径可能挂载在 LVM、RAID 或 btrfs 子卷下。
立即学习“C++免费学习笔记(深入)”;
- 用
stat()获取路径所在文件系统的st_dev - 遍历
/proc/mounts或调用getmntent()找到对应挂载点的块设备路径(如/dev/nvme0n1p1) - 提取设备主次号,或从设备路径解析出 basename(如
nvme0n1p1→nvme0n1),再拼接/sys/block/{name}/queue/rotational - 某些 NVMe 设备(尤其带命名空间的)可能不暴露
rotational,此时可 fallback 到检查/sys/block/{name}/device/model是否含NVME或SSD字样
macOS 下通过 IOKit 获取 kIOBlockStorageDeviceMediumTypeKey
macOS 需用 IOKit 框架查存储设备属性,核心是拿到路径对应卷的 IOMedia 对象,再读取 kIOBlockStorageDeviceMediumTypeKey。值为 kIOBlockStorageDeviceMediumTypeSolidState 即确认为 SSD。
容易卡在设备树遍历层级:路径 → mountpoint → disk device → parent IOMedia(可能是 Logical Volume)→ Physical Media。跳过中间 Logical Volume 直接找最顶层的 Physical Media 才能拿到真实介质类型。
- 用
statfs()获取路径所在卷的f_mntfromname(如/dev/disk2s1) - 用
IOServiceGetMatchingServices()匹配IOBSDNameMatching(kIOMasterPortDefault, "disk2s1") - 向上调用
IORegistryEntryCreateIterator()找到类型为IOMedia且Content为AppleAPFSMedia或ApplePartitionScheme的父节点 - 调用
IORegistryEntryCreateCFProperties()提取kIOBlockStorageDeviceMediumTypeKey,比较是否等于kIOBlockStorageDeviceMediumTypeSolidState
跨平台封装要注意的兼容性陷阱
没有一种方法能在所有系统版本上 100% 准确。Windows 7 不支持 MSFT_PhysicalDisk,得降级用 Win32_DiskDrive + Model 字段关键词匹配;Linux 上某些厂商定制内核会把 SSD 的 rotational 写成 1;macOS Monterey 后部分 APFS 加密卷的 IOMedia 层级关系也变了。
- 永远 fallback:当系统 API 返回异常或缺失字段时,优先采信
rotational=0(Linux)、MediaType=3/4(Windows)、MediumType==SolidState(macOS),其余情况默认不认为是 SSD - 不要依赖设备型号字符串(如含 “SSD” 就判定),有些机械硬盘厂商也会在 Model 里写 SSD
- 缓存结果很重要:同一路径反复查询不应每次都走 WMI/sysfs/IOKit,建议按设备 ID(如 Windows 的
DeviceID、Linux 的MAJ:MIN)做内存缓存,有效期设为进程生命周期即可
实际写的时候,最麻烦的不是查介质类型,而是把任意路径稳稳落到最底层物理设备上——中间任何一层抽象(LVM、ZFS、BitLocker、APFS 加密卷)都可能打断这个链路。


















