当前位置:

首页 > 编程开发 > C++如何获取硬盘分区的详细挂载信息 _ filesystem库实战【实战】

C++如何获取硬盘分区的详细挂载信息 _ filesystem库实战【实战】

C++如何获取硬盘分区的详细挂载信息 _ filesystem库实战【实战】 std::filesystem::space() 能不能拿到挂载点路径? 答案是:不能。很多开发者会误以为std::filesystem::space()能提供完整的磁盘信息,其实它只负责一件事:返回指定路径所在文件系统的

C++如何获取硬盘分区的详细挂载信息 _ filesystem库实战【实战】

C++如何获取硬盘分区的详细挂载信息 _ filesystem库实战【实战】

std::filesystem::space() 能不能拿到挂载点路径?

答案是:不能。很多开发者会误以为std::filesystem::space()能提供完整的磁盘信息,其实它只负责一件事:返回指定路径所在文件系统的空间统计,也就是capacityfreea vailable这三个数字。至于这个空间属于哪个分区、挂载点路径是什么、文件系统类型为何,它一概不告诉你。

这就好比问一个仓库管理员“库房里还有多少空位”,他能给你一个准确的数字,但你要问他“这个仓库在哪个园区、门牌号多少、用什么锁”,他就无能为力了。你传入"C:/""/home",它只会埋头计算该路径所在的文件系统空间,绝不会反过来告诉你对应的设备名或挂载配置。

Linux 下怎么拿到 /proc/mounts 里的真实挂载项

既然标准库不提供,那就得用系统自己的方法。在Linux环境下,没有跨平台的通用接口,最直接可靠的方式就是去读取系统文件。这里有个关键区别:要获取当前实际生效的挂载信息,应该解析/proc/mounts,这是内核提供的实时视图;而不是去读/etc/fstab,那只是静态配置文件,里面的条目不一定都已经挂载上了。

具体怎么操作呢?

  • 文件格式/proc/mounts的每一行都遵循固定格式:设备名、挂载点、文件系统类型、挂载选项、dump标志、pass标志,各字段之间用空格分隔。需要注意的是,挂载点路径和挂载选项字符串内部可能包含空格或特殊字符,解析时不能简单按空格切割,得根据字段数量进行容错处理。
  • 解析步骤:推荐使用std::ifstream逐行读取,然后用std::istringstream进行分词。我们主要关心第2列(挂载点)、第3列(文件系统类型fstype)和第4列(挂载选项opts)。
  • 数据过滤:记得跳过以#开头的注释行。更重要的是,像rootfssysfsproc这类伪文件系统并非实际的硬盘分区,通常需要将它们过滤掉,只保留物理磁盘或网络存储等条目。
  • 代码片段示例
    std::string line;
    while (std::getline(fs, line)) {
        if (line.empty() || line[0] == '#') continue;
        std::istringstream iss(line);
        std::string dev, mountpoint, fstype, opts;
        if (iss >> dev >> mountpoint >> fstype >> opts) {
            if (fstype != "rootfs" && fstype != "sysfs" && fstype != "proc") {
                // 此时,mountpoint 和 fstype 就是我们需要的信息
            }
        }
    }

Windows 怎么枚举驱动器并获取卷信息

Windows的哲学与Linux不同,它没有明确的“挂载点”概念,取而代之的是驱动器字母。不过,我们可以通过一组API组合来获取等效信息。

  • 枚举驱动器:使用GetLogicalDrives()函数,它会返回一个位掩码(bitmask),每一位代表一个存在的驱动器字母(例如C:、D:)。遍历这个掩码就能得到所有有效的盘符。
  • 获取详细信息:对于每一个有效的驱动器,调用GetVolumeInformation(L"C:\\", ...)。这个函数能提供丰富的卷信息,包括卷标(lpVolumeNameBuffer)、文件系统名称(lpFileSystemNameBuffer,如“NTFS”、“FAT32”)、卷序列号等。这里有个细节要注意:传入的路径必须是带有尾部反斜杠的根路径(如L"C:\\"),否则调用会失败。另外,lpVolumeNameBuffer有可能为空字符串,这表示该卷没有设置卷标。
  • 关于挂载选项:Windows没有直接对应Linux挂载选项的概念。但是,一个高级功能是,同一个物理卷可以被挂载到多个路径。你可以使用GetVolumePathNamesForVolumeName()来查询某个卷的所有挂载路径。例如,一个NTFS卷可能同时被挂载到C:D:\data

跨平台封装时最容易漏掉的三个细节

当你试图将这些逻辑封装成一个统一的接口时,注意力往往集中在获取路径和类型这些主要信息上。然而,下面这三个细节如果被忽略,你的程序在复杂的真实环境中很可能 silently fail(静默失效)。

立即学习“C++免费学习笔记(深入)”;

  • Linux符号链接问题/proc/mounts中列出的挂载点,有可能是一个符号链接(例如/home → /mnt/data/home)。如果你直接用读到的字符串与用户传入的路径进行比较,可能会因为路径形式不一致而失败。稳妥的做法是,使用std::filesystem::canonical()函数将路径归一化,消除符号链接的影响。
  • Windows驱动器状态问题:不是所有通过GetLogicalDrives()检测到的驱动器都是可立即访问的。例如,光驱里没有光盘,或者USB设备已被拔出,这些驱动器是“存在但不可用”的状态。在调用GetVolumeInformation()之前,应该先用GetDriveType()检查驱动器类型。通常我们只关心DRIVE_FIXED(固定硬盘)或DRIVE_REMOVABLE(可移动磁盘),而对于DRIVE_NO_ROOT_DIR(没有根目录)这类状态,直接跳过即可。
  • 权限与环境的坑:在Linux上,普通用户通常可以读取/proc/mounts,但在某些安全加固过的系统(比如特定配置的容器环境或开启了严格SELinux策略的主机)下,访问可能会被屏蔽。在Windows上,获取大部分基础卷信息不需要管理员权限,但如果你想查询诸如BitLocker加密状态等高级属性,则可能需要提权。编写代码时要考虑这些边界情况,做好错误处理。

说到底,真正的挑战从来不是“如何读取数据”,而是“如何确保读取到的数据在千变万化的运行环境中是可信的”。举个例子,/proc/mounts里有一行记录:/dev/sdb1 /mnt/usb vfat rw,nosuid...。你的程序不能假设这条记录一定有效。更严谨的做法是,在获取信息后,加一步简单的验证,比如调用std::filesystem::exists("/mnt/usb"),确认这个挂载点当前确实可访问,而不是一个已被卸载但残留的条目。这一步小小的检查,往往比复杂的逻辑更能保证程序的健壮性。

本文内容来源于互联网,如有侵权请联系删除。
作者最新文章
编程开发 硬盘 C++
相关文章 更多
C++动态数组初始化怎么写?常用语句与代码示例
C++动态数组初始化怎么写?常用语句与代码示例

深入解析C++中动态数组的初始化机制,涵盖new操作符的不同用法、基本类型与类对象的初始化差异,以及为何在现代C++开发中应优先使用std::vector。

WMV转MP4方法
WMV转MP4方法

WMV视频压缩指南:如何高效“瘦身”释放硬盘空间 在日常处理和收藏视频时,不少人会发现一个有趣的现象:WMV格式的文件,在画质相当的情况下,体积往往比MP4更小巧。这原本是它的优势,但架不住日积月累,一堆WMV文件同样会悄悄吃掉大量的硬盘空间。因此,如何给WMV视频“减减肥”,就成了优化存储、提升效

C++类构造与析构函数详解
C++类构造与析构函数详解

C++类构造与析构函数详解 C++这门语言,可以说是从C语言这棵大树上衍生出的高级果实,如今的应用普及度有目共睹。作为一种静态类型的通用编程语言,它厉害的地方在于融合了多种编程哲学——无论是传统的面向过程,还是主流的面向对象,乃至数据抽象、泛型编程这些高级概念,它都能很好地支持。正因为这份卓越的扩展

C++中std::upper
C++中std::upper

C++中std::upper_bound用法解析 在C++标准模板库(STL)的算法工具箱里,upper_bound() 绝对算得上是一把精准的“探针”。它的核心任务很明确:在一个已经排好序的区间 [first, last) 内,帮你快速定位到第一个**严格大于**指定值 value 的那个元素。这

C++常对象与成员解析
C++常对象与成员解析

C++中“常”概念全景解析:从对象、成员到指针与引用 在C++的世界里,“常量性”是一个强大的保障机制。它不仅仅是一个const关键字那么简单,而是构建健壮、安全程序的重要基石。今天,我们就来系统梳理一下围绕“常”的一系列概念:常成员、常对象、常指针与常引用。理解它们,是写出高质量C++代码的关键一

using namespace 使用中遇到的问题怎么解决
using namespace 使用中遇到的问题怎么解决

命名空间的基本概念与常见引入问题在C++等编程语言中,命名空间(namespace)是一种将代码标识符(如变量、函数、类名)封装在特定名称下的机制,其主要目的是避免命名冲突,尤其是在大型项目或使用多个第三方库时。使用“using namespace”指令可以将指定命名空间中的所有名称引入当前作用域,

c语言函数递归 实操经验总结:这些技巧很实用
c语言函数递归 实操经验总结:这些技巧很实用

理解递归的基本原理在C语言中,递归是一种函数调用自身的编程技术。要掌握它,首先需要理解其核心思想:将一个复杂的大问题,分解为一个或几个与原问题相似但规模更小的子问题,直到子问题足够简单,可以直接求解。这个过程通常包含两个关键部分:递归出口和递归体。递归出口定义了问题何时不再继续分解,即最简单、可直接

c语言函数递归 怎么选?常见方案对比分析
c语言函数递归 怎么选?常见方案对比分析

递归函数的基本概念与适用场景在C语言编程中,递归是一种函数调用自身的编程技巧。它并非适用于所有问题,但在处理某些具有自相似结构的问题时,能提供极其清晰和优雅的解决方案。递归的核心思想是将一个大规模问题分解为一个或多个同类型但规模更小的子问题,直到子问题简单到可以直接求解。典型的适用场景包括树形结构的

Objective-C 内存管理入门:从 alloc 到 dealloc 的生命周期详解
Objective-C 内存管理入门:从 alloc 到 dealloc 的生命周期详解

理解内存管理的基石在Objective-C的编程世界中,内存管理是开发者必须掌握的核心技能之一。它直接关系到应用的性能、稳定性与资源利用效率。与一些采用自动垃圾回收机制的语言不同,Objective-C在很长一段时间里,依赖一套基于引用计数的、需要开发者部分介入的管理规则。这套规则的核心思想是明确的

查看更多
精品专题 更多
装机必备
装机必备

正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

Windows
Windows

正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

macOS软件
macOS软件

正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

Mac软件 更多
灵活计算器
灵活计算器
macOS/iOS/Android

灵活计算器是一款笔记式算数应用,支持实时计算、动态关联和云端同步功能。记录、整理和输出之间的过渡会更自然,适合长期写作、做笔记或持续沉淀个人内容。

赤友清理大师
赤友清理大师
macOS

赤友清理大师是一款为 Mac 设计的智能清理优化工具,可精准扫描垃圾、大文件、重复文件等,释放磁盘空间。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

极度公式
极度公式
Windows/macOS/Linux

极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

WINDOWS 更多
Windows 10
Windows 10
Windows

Windows 10 是一款微软推出的经典操作系统,拥有硬件兼容性与多任务处理能力。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。

极度公式
极度公式
Windows/macOS/Linux

极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

密码键盘
密码键盘
Windows/macOS/iOS/Android

密码键盘是一款兼具安全性与便捷性的高效密码管理器。日常使用里的持续防护和信息管理会更突出,适合把安全控制放进长期使用流程中的场景。