linux下判断路径是否位于ssd的最可靠方法是读取/sys/block/*/queue/rotational:值为0表示非旋转介质(通常为ssd/nvme),1为hdd;需先用stat()获取st_dev并提取主次设备号,再通过/sys/dev/block/:或/proc/mounts映射到实际设备名后读取该文件。

Linux 下通过 ioctl 查询块设备是否为 SSD
Linux 内核从 2.6.33 起支持 BLKGETDISKSEQ 和更实用的 BLKSSZGET 配合 sysfs 判断 SSD,但最直接可靠的是读取 /sys/block/*/queue/rotational:值为 0 表示非旋转介质(通常是 SSD),1 表示 HDD。
关键步骤是:先用 stat() 获取文件所在设备的主次设备号(st_dev),再解析 /proc/self/mountinfo 或 /sys/dev/block/<major>:<minor></minor></major> 找到对应 block 设备名(如 sda、nvme0n1),最后读取 /sys/block/<device>/queue/rotational</device>。
-
stat()的st_dev字段给出设备 ID,注意它不是简单的整数,需用major(st_dev)和minor(st_dev)宏提取 -
/sys/dev/block/是符号链接,指向/sys/block/xxx,可直接readlink解析 - 某些 NVMe 设备(如
nvme0n1)在rotational中恒为0,但个别老旧固件可能误报;机械盘几乎不会伪造为0
Windows 下用 IOCTL_STORAGE_QUERY_PROPERTY 检查存储类型
Windows 不暴露“SSD”布尔标识,而是通过 STORAGE_DEVICE_DESCRIPTOR 中的 DeviceType 和 MediaType 间接推断。更准确的方式是发送 IOCTL_STORAGE_QUERY_PROPERTY 请求 StorageDeviceSeekPenaltyProperty —— SSD 返回 SeekPenaltyEnabled=FALSE,HDD 通常为 TRUE。
实操中需注意:CreateFile 必须以 FILE_SHARE_READ | FILE_SHARE_WRITE 打开卷根路径(如 \.C:),而非普通文件路径;且调用前要确保有管理员权限(部分设备属性受保护)。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 获取卷路径要用
GetVolumePathName,不能直接对C:\foo.txt调用CreateFile -
STORAGE_DEVICE_DESCRIPTOR中BusType为BusTypeNVMe或BusTypeUSB时,MediaType可能不可靠,优先依赖SeekPenaltyProperty - 返回
ERROR_ACCESS_DENIED很常见,换用OpenVolume+SetFileSecurity不现实,建议降级 fallback 到检查BusType和型号字符串(如含 “SSD”、“NVME”)
C++ 跨平台封装的实用边界
没有跨平台标准 API 能 100% 确定 SSD,因为“SSD”本身是硬件+固件+驱动共同呈现的行为特征,不是操作系统定义的元数据。所谓“判断”,本质是查某几个高概率指标的组合。
- Linux 下
/sys/block/*/queue/rotational是首选,但某些 Intel Optane 或混合缓存盘(如某些 Intel RST RAID)可能返回1却表现接近 SSD - Windows 下
SeekPenaltyProperty在 Windows 8+ 可靠,但 Windows 7 只能靠BusType和DeviceId字符串启发式匹配(易误判 USB SSD) - 不要尝试用性能测试(如随机 I/O 延迟)反推——用户权限、I/O 调度器、文件系统缓存都会干扰结果
代码里最容易漏掉的三件事
写完逻辑常以为搞定,实际部署时大概率卡在这三处:
- 没处理
stat()失败(如路径不存在、权限不足),直接用未初始化的st_dev查设备 → 解析出乱码路径或崩溃 - Linux 下读
/sys/block/xxx/queue/rotational忘了open()加O_RDONLY,或没忽略 trailing newline(read()返回 2 字节:'0 ') - Windows 下没调用
GetLastError()区分ERROR_INSUFFICIENT_BUFFER(需重试更大 buffer)和真实错误,导致属性读取失败却静默返回假阴性
物理位置判断永远带不确定性,尤其在虚拟化环境、LVM、btrfs raid 或 Windows Storage Spaces 下,rotational 或 SeekPenalty 可能反映的是底层虚拟设备特性,而非真实 NAND。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










