C++ 如何获取硬盘分区的详细挂载位置与扇区大小信息实战案例应用【实战】

酷萱小哥_6919

酷萱小哥_6919

2026-05-27

579人浏览

原创

Linux下应先用statfs定位挂载点,再open对应块设备并ioctl(BLKSSZGET/BLKPBSZGET)分别获取逻辑与物理扇区大小;Windows需用DeviceIoControl+IOCTL_DISK_GET_DRIVE_GEOMETRY_EX查询BytesPerSector和PhysicalBytesPerSector。

c++ 如何获取硬盘分区的详细挂载位置与扇区大小信息实战案例应用【实战】

Linux 下用 statfs 和 ioctl 获取挂载点与逻辑/物理扇区大小

直接读 /proc/mounts 只能拿到挂载路径和文件系统类型,拿不到扇区大小;statvfs 也不提供物理扇区信息。真实需求(比如做底层块设备对齐、RAID 配置校验)必须区分逻辑扇区(LOGICAL_BLOCK_SIZE)和物理扇区(PHYSICAL_BLOCK_SIZE),这两者在 SSD 或 Advanced Format 硬盘上常不一致。

核心做法是:先通过 statfs 或遍历 /proc/mounts 定位挂载点 → 对挂载点路径调用 open("/dev/xxx", O_RDONLY) 拿到块设备 fd → 再用 ioctl(fd, BLKSSZGET, &logical) 和 ioctl(fd, BLKPBSZGET, &physical) 分别获取。

  • BLKSSZGET 返回逻辑扇区大小(通常是 512 或 4096),BLKPBSZGET 是内核 2.6.32+ 才支持的物理扇区查询,老内核会返回 EINVAL
  • 注意:不能对普通文件或挂载点目录直接 ioctl,必须打开对应底层块设备。可从 /sys/block/*/slaves/ 或 readlink /sys/block/*/device 反查,但更稳的方式是解析 /proc/self/mountinfo 中的 major:minor,再映射到 /dev 下设备
  • 示例片段:
    int fd = open("/dev/sda1", O_RDONLY);<br>int logical = 0, physical = 0;<br>ioctl(fd, BLKSSZGET, &logical);<br>ioctl(fd, BLKPBSZGET, &physical); // 可能失败,需检查 errno

Windows 下用 GetDiskFreeSpaceEx 和 DeviceIoControl 获取卷信息

Windows 没有“挂载点”概念,只有卷(volume)和驱动器号(如 C:)。GetDiskFreeSpaceEx 能拿到簇大小(即文件系统分配单元),但它不是扇区大小——NTFS 默认簇是 4KB,而底层磁盘扇区可能是 512B 或 4KB。

真正需要扇区大小时,必须走设备控制接口:CreateFile(L"\.C:", ...) 打开卷设备 → DeviceIoControl(..., IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, ...) → 结构体中 DiskGeometry.BytesPerSector 是逻辑扇区,DiskGeometry.PhysicalBytesPerSector(Win8+)才是物理扇区。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 打开卷设备时权限要足:GENERIC_READ + FILE_SHARE_READ | FILE_SHARE_WRITE,否则 CreateFile 失败
  • IOCTL_DISK_GET_DRIVE_GEOMETRY_EX 在 Windows 7 及以下不返回 PhysicalBytesPerSector 字段,需降级用 IOCTL_STORAGE_QUERY_PROPERTY 查 StorageAccessAlignmentProperty
  • 不要用 GetDriveType 判断是否为硬盘——RAM disk、iSCSI 卷也返回 DRIVE_FIXED,得结合 IOCTL_STORAGE_GET_DEVICE_NUMBER 看设备类型

跨平台封装时绕不开的设备路径映射问题

Linux 的 /dev/sda1 和 Windows 的 \\.\C: 表面都是“设备路径”,但语义完全不同:前者是块设备节点,后者是卷设备句柄。同一块 SSD 在 Linux 下可能有多个分区(sda1, sda2),在 Windows 下却只对应一个卷(C:),且没有标准 API 把 C: 映射回 sda1 ——因为 Windows 不暴露底层分区名。

这意味着:跨平台工具若想统一处理,必须放弃“用一个字符串表示设备”的幻想,改用两级抽象:

  • 第一层:运行时识别当前 OS + 获取所有活跃挂载/卷列表(Linux 读 /proc/mounts,Windows 调 GetVolumePathNamesForVolumeNameW)
  • 第二层:对每个条目,按平台规则构造设备访问路径(Linux 查 /sys/dev/block/M:m,Windows 用 FindFirstVolume + GetVolumeNameForVolumeMountPoint)
  • 常见坑:statfs 对 /boot 返回的 f_fsid 和 stat 对 /dev/sda1 的 st_dev 无直接关系;Windows 的 QueryDosDevice 也不能把 C: 变成 DeviceHarddiskVolume1 的稳定映射

实际应用中扇区大小误判导致的典型故障

很多工具(如自定义日志写入器、数据库页刷盘模块)假设扇区是 512B,直接按 512 对齐 buffer,结果在 4K 扇区硬盘上触发“读-修改-写”放大,性能暴跌 3–5 倍。这不是理论风险,而是线上真实发生过的 case。

  • 最隐蔽的坑:posix_memalign 分配 4096 对齐内存 ≠ 确保 I/O 对齐——你还得用 O_DIRECT(Linux)或 FILE_FLAG_NO_BUFFERING(Windows),且 buffer 地址、offset、length 全部按物理扇区对齐
  • hdparm -I /dev/sda 输出里的 “Logical/Physical Sector size” 是权威来源,但 C++ 程序不能依赖外部命令——必须走系统调用,否则容器环境或最小化系统里 hdparm 根本不存在
  • 虚拟化环境(如 KVM/QEMU)下,guest OS 看到的扇区大小由 qemu 参数(logical_block_size=4096,physical_block_size=4096)决定,和宿主机硬盘无关,这点常被忽略

物理扇区对齐不是“设个 flag 就完事”的事,它要求你准确知道设备路径、正确打开设备句柄、容错处理 ioctl 失败、并在 I/O 路径全程保持对齐约束。漏掉任一环,都可能让优化变成负优化。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2288

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

1039

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

447

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

347

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

426

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

600

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1429

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1237

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1325

9

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习