Linux下通过stat获取st_dev,结合/proc/mounts或findmnt定位块设备,再读取/sys/block/xxx/queue/rotational值(0为SSD,1为HDD)是最可靠方法;Windows需用IOCTL_STORAGE_QUERY_PROPERTY查DeviceCharacteristics中FILE_DEVICE_IS_SSD标志,且需管理员权限。

Linux 下用 stat 和 lsblk 判断 SSD 分区归属
直接看设备属性比猜路径更可靠。C++ 本身不提供“这个路径在 SSD 上吗”的 API,得靠系统信息反推:先获取文件所在挂载点,再查该设备是否标记为 SSD。
关键步骤是:stat 获取文件的 st_dev,用它查 /proc/mounts 或 findmnt 找到对应块设备(如 /dev/nvme0n1p2),再读取该设备的 rotational 值——0 表示 SSD,1 表示 HDD。
-
stat -c "%d" /path/to/file输出十进制设备号,需转为十六进制后匹配/sys/dev/block/*/dev - 更稳妥的做法是调用
findmnt -n -o SOURCE /path/to/file直接拿到块设备路径 -
cat /sys/block/nvme0n1/queue/rotational返回0即 SSD;注意设备名要去掉分区号(nvme0n1p2→nvme0n1)
C++ 中调用 statfs 和解析 /proc/mounts 的实操要点
不能只依赖 stat(),它只给 inode 和设备号,不带挂载信息。必须结合 statfs() 或 getmntent() 查挂载表。
推荐流程:用 stat() 得到 st_dev → statfs() 获取挂载点路径 → 在 /proc/mounts 中按挂载点匹配设备名 → 解析设备名、裁剪分区后缀 → 读 /sys/block/xxx/queue/rotational。
立即学习“C++免费学习笔记(深入)”;
-
statfs()的f_fsid字段在某些文件系统(如 overlayfs)下不可靠,优先用挂载路径匹配 - 解析
/proc/mounts时注意空格和转义,建议用std::regex或逐字段strtok_r,别用简单std::string::find(" ") - 设备路径可能含 UUID 或 LABEL,此时需通过
readlink /dev/disk/by-uuid/xxx转成真实路径
Windows 下只能靠 IOCTL_STORAGE_QUERY_PROPERTY 和 GET_DISK_GEOMETRY_EX
Windows 没有统一“SSD 标记”,得组合判断:先用 CreateFile 打开卷根目录(如 \\?\C:),再发两个 IOCTL:
-
IOCTL_STORAGE_QUERY_PROPERTY查StorageDeviceProperty,看DeviceCharacteristics是否含FILE_DEVICE_IS_SSD(Windows 10 1809+ 支持) - fallback 方案:用
GET_DISK_GEOMETRY_EX获取DiskSize和BytesPerSector,再查IOCTL_ATA_PASS_THROUGH获取 IDENTIFY DEVICE 数据,解析第 217 字节 bit 2(ROTATION_RATE)是否为 0 - 注意:普通用户权限无法对物理磁盘句柄执行 ATA 透传,需管理员权限 +
FILE_SHARE_WRITE
跨平台封装要注意的三个坑
别写“一次编写,到处判断 SSD”——Linux 和 Windows 的判定逻辑、权限模型、错误路径完全不同。
- Linux 下
/sys/block/xxx/queue/rotational文件可能不存在(比如某些 NVMe 驱动没暴露该属性),要容错返回unknown,而非报错 - Windows 下
FILE_DEVICE_IS_SSD在旧系统或虚拟磁盘(如 WSL2 虚拟硬盘)上恒为 false,不能当作唯一依据 - 符号链接、bind mount、overlayfs 等场景会让路径和实际物理设备脱钩,务必用
stat()+statfs()组合确认真实挂载点,而不是直接realpath()后截取盘符
真正难的不是读一个文件,而是把路径、挂载、设备、驱动特性这四层关系理清楚——漏一层,判断就可能错。


















