Linux 通过 stat 获取设备号后读取 /sys/block/*/queue/rotational 判断 SSD(0)或 HDD(1);Windows 需用 DeviceIoControl 查询 STORAGE_DEVICE_DESCRIPTOR 的 BusType 和 MediaClass;macOS 依赖 IOKit 获取 kIOBlockStorageDeviceIsSolidStateKey;跨平台推荐行为测试或用户显式配置而非硬件探测。

Linux 下用 stat 查设备类型再查 /sys/block/*/queue/rotational
Linux 没有直接 API 告诉你“这个路径在 SSD 上”,得靠间接推断:先拿到路径对应的块设备(如 sda),再读取该设备的 rotational 值。值为 0 表示非旋转介质(大概率是 SSD/NVMe),1 表示 HDD。
实操分三步:
- 用
stat -c "%d" /path获取设备主次号(decimal),或 C++ 中调用stat()填充struct stat,取st_dev - 用
major(st_dev)和minor(st_dev)(需#include)提取主次设备号 - 拼出 sysfs 路径:
/sys/dev/block/MAJOR:MINOR/device/queue/rotational(注意:部分 NVMe 设备路径是/sys/dev/block/MAJOR:MINOR/queue/rotational,需 fallback 尝试)
读到的文件内容是单字节字符 '0' 或 '1',别忘了 strip 换行符。注意权限问题:普通用户可能无法读 /sys 下某些路径,建议加 open(..., O_RDONLY | O_CLOEXEC) 并检查返回值。
Windows 下用 GetDriveType + IOCTL_STORAGE_QUERY_PROPERTY
GetDriveType 只能区分“可移动”“固定”“网络”等大类,不能识别 SSD。真要判断,必须走存储驱动接口。
关键步骤:
- 从路径提取盘符,例如
"C:\foo"→"C:",再调用GetVolumePathName确保得到根路径 - 用
CreateFile打开\\.\C:(注意双反斜杠和冒号),权限设为0,标志含FILE_SHARE_READ | FILE_SHARE_WRITE - 构造
STORAGE_PROPERTY_QUERY,PropertyId = StorageDeviceProperty,QueryType = PropertyStandardQuery,传给DeviceIoControl获取STORAGE_DEVICE_DESCRIPTOR - 检查返回结构体里的
BusType:若为BusTypeNvme或BusTypeSata且MediaClass == MediaClassSSD(Win10 1903+ 才稳定支持该字段),才较可信
注意:MediaClass 在旧系统里常为 MediaClassUnspecified,此时只能退而求其次看 BusType + VendorId + 启动时间等启发式线索——但这就不是程序能 100% 判断的事了。
macOS 下靠 ioctl + DKIOCGDISKINFO 和 IOKit
macOS 没公开 SSD 标识字段,但可通过磁盘特性反推。最可靠的是用 IOKit 查询 kIOBlockStorageDeviceCharacteristicsKey 字典中的 kIOBlockStorageDeviceIsSolidStateKey(值为布尔型)。
简化流程:
- 用
stat()得到路径的st_dev,再调用DKIOCGDISKINFOioctl(需打开/dev/diskX对应设备)获取dk_size和dk_name - 用
IOServiceGetMatchingServices匹配IOBSDNamesMatching(如"disk0s1"→"disk0"),再向上找IOBlockStorageDevice父类 - 调用
IORegistryEntryCreateCFProperties提取特性字典,检查kIOBlockStorageDeviceIsSolidStateKey是否存在且为kCFBooleanTrue
缺点是依赖 IOKit 框架,编译需链接 -framework IOKit,且沙盒应用默认无权访问设备节点。普通命令行工具可行,App Store 应用基本不可行。
跨平台不推荐硬判断,优先用场景逻辑代替
真正需要“是否 SSD”的业务,往往其实关心的是“是否低延迟”或“是否适合随机写”。与其花力气猜硬件类型,不如直接测行为:
- 用
clock_gettime(CLOCK_MONOTONIC)测小文件write()+fsync()的 P95 延迟,20ms 很可能是 HDD - 对数据库、日志等场景,直接把路径加入配置项,让用户明确指定
storage.type = "ssd"或"hdd",比自动探测更可靠 - Linux 下可查
/sys/block/*/rota(新内核简写)或lsblk -d -o NAME,ROTA,但这是设备级,不是路径级——同一块盘上不同分区必然同类型
最后提醒:NVMe 设备可能被 BIOS 设置成 RAID 模式,此时操作系统看到的是 RAID 卡设备,rotational 常为 1,但实际性能仍是 SSD 级。这种 case,代码永远判不准。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











