最可靠的方法是使用ioctl_storage_query_property查询storagedeviceseekpenaltyproperty:ssd寻道惩罚值为0,hdd通常非零;需将路径转为“?c:”格式并以file_share_read|file_share_write打开物理卷句柄。

Windows下用GetDriveType和GetVolumeInformation只能判断驱动器类型,不能确认是否SSD
很多开发者误以为GetDriveType返回DRIVE_FIXED就代表SSD,其实它只区分软盘、U盘、网络盘、固定硬盘等大类,不区分HDD和SSD。同样,GetVolumeInformation返回的文件系统信息(如NTFS)也完全无关。真正能反映物理介质特性的,是Windows存储驱动栈暴露的设备能力标识。
用IOCTL_STORAGE_QUERY_PROPERTY查StorageDeviceSeekPenaltyProperty
这是最可靠的方法:SSD的寻道惩罚值(seek penalty)为0,而HDD通常非零。需要打开物理卷句柄(不是普通文件句柄),并发送设备控制码。关键点:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 路径需先转为卷根格式,例如
"C:\test\file.txt"→"\\?\C:"(注意双反斜杠+问号前缀) - 必须用
FILE_SHARE_READ | FILE_SHARE_WRITE打开,否则CreateFile会失败 -
STORAGE_DEVICE_SEEK_PENALTY_DESCRIPTOR结构体中IncursSeekPenalty字段为FALSE即大概率是SSD - 部分NVMe盘或启用了Write Cache的SATA SSD可能返回
TRUE,需结合其他属性交叉验证
补充查StorageDeviceTrimProperty和StorageAdapterProtocolProperty
单独依赖seek penalty不够稳健,建议组合判断:
-
StorageDeviceTrimProperty:SSD普遍支持TRIM(TrimEnabled == TRUE),HDD基本不支持(但某些RAID卡可能伪造) -
StorageAdapterProtocolProperty:检查ProtocolType字段,ProtocolTypeNvme或ProtocolTypeSas(配合SSD固件)比ProtocolTypeAta更可能是SSD,但SATA SSD也是ProtocolTypeAta - 如果
SeekPenalty为0 且TrimEnabled为true,基本可断定是SSD;若两项冲突,优先信SeekPenalty,因为TRIM可被禁用或模拟
Linux下通过/sys/block/*/queue/discard_granularity和rotational文件判断
Linux没有统一API,靠sysfs暴露的底层特性:
-
/sys/block/sda/queue/rotational值为0表示非旋转介质(SSD/NVMe),1为HDD —— 这是最常用、最轻量的判断依据 -
/sys/block/sda/queue/discard_granularity> 0 通常说明支持TRIM,但HDD RAID卡也可能返回非零值,不可单独依赖 - 路径转换:先用
stat获取文件所在块设备名(st_dev→major/minor→/sys/dev/block/*),再读对应rotational文件 - 注意容器或虚拟化环境可能透传错误值,
rotational为0不绝对等于物理SSD(比如某些NVMe over Fabrics配置)
rotational和SeekPenalty虽是核心指标,但都可能被中间层覆盖或模拟。真要严格区分,得结合SMART数据(如Media_Wearout_Indicator)或WMI/CIM查询MSFT_PhysicalDisk类,不过那已是运维级操作了。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










