导读:本期聚焦于小伙伴创作的《C++如何获取硬盘分区的详细挂载点与剩余空间信息?》,敬请观看详情。在跨平台桌面工具开发中,准确拿到每个分区的挂载路径和可用容量常常决定功能能否落地。Linux下可读取/proc/mounts配合statvfs得到挂载点与剩余块数,Windows则需调用GetLogicalDriveStringsW枚举盘符再用GetDiskFreeSpaceExW查询。若直接用系统API写一遍,代码分散且易忽略权限错误。本文对比手工调用与Boost.FileSystem、std::filesystem两种方案,指出C++17标准库已内置space方法但拿不到挂载点,需要自行补齐挂载信息。实战中建议将挂载点扫描封装为独立模块,空间统计走标准库,既减少依赖也方便单测。

在编写系统监控、文件备份或资源调度类程序时,C++开发者往往要同时掌握两件事:一是机器上所有存储卷挂到了哪个目录,二是每块卷还剩多少空间可写。不同操作系统的接口差异很大,如果只在某一种环境调通,换平台就可能拿到空数据或触发权限异常。因此理解底层机制和可选封装库,是写出稳定工具的前提。

C++如何获取硬盘分区的详细挂载点与剩余空间信息?

Linux环境下读取挂载点与剩余空间的原生方式

在Linux系统中,所有已挂载的文件系统都会记录在虚拟文件/proc/mounts里。每一行描述一个挂载实例,字段依次是设备名、挂载点、文件系统类型以及挂载参数。我们可以通过标准文件流打开这个文件,按行解析,提取第二个字段作为挂载路径。需要注意的是,有些挂载点属于内存盘或特殊文件系统,比如tmpfs、proc,它们虽然出现在列表里,但并不一定代表真实的物理硬盘分区,实战中通常要结合文件系统类型做一层过滤。

拿到挂载点目录之后,剩余空间信息可以通过statvfs系统调用获取。该函数填充一个struct statvfs结构,其中的f_bsize表示块大小,f_bfree是未使用的块数量,f_blocks是总块数。用f_bfree乘以f_bsize就能得到自由字节数。下面示例展示如何扫描/proc/mounts并计算某个挂载点的可用空间:

#include <fstream>
#include <string>
#include <vector>
#include <sys/statvfs.h>
#include <iostream>

struct MountInfo {
    std::string device;
    std::string mount_point;
    std::string fs_type;
};

std::vector<MountInfo> read_mounts() {
    std::vector<MountInfo> result;
    std::ifstream file("/proc/mounts");
    std::string line;
    while (std::getline(file, line)) {
        // 简单按空格切分,真实场景建议用更严谨的解析
        std::istringstream iss(line);
        MountInfo info;
        iss >> info.device >> info.mount_point >> info.fs_type;
        result.push_back(info);
    }
    return result;
}

long long get_free_bytes(const std::string& path) {
    struct statvfs buf;
    if (statvfs(path.c_str(), &buf) != 0) {
        return -1;
    }
    return (long long)buf.f_bfree * (long long)buf.f_bsize;
}

int main() {
    auto mounts = read_mounts();
    for (auto& m : mounts) {
        long long free = get_free_bytes(m.mount_point);
        std::cout << m.mount_point << " free:" << free << std::endl;
    }
    return 0;
}

这种原生做法的优点是不依赖任何第三方库,只要系统提供procfs和POSIX接口就能编译运行。缺点在于解析/proc/mounts需要自己处理转义字符,例如挂载点路径中的空格会被写成40,直接按空格切分就会出错。此外statvfs对某些特殊挂载可能返回零值,需要调用方判断有效性。

为了更健壮,有些项目会改读/etc/mtab或者利用mount命令输出,但原理类似。在容器环境里,/proc/mounts看到的是容器视角,若想获取宿主机真实磁盘,还需额外权限。因此原生方案适合对依赖敏感、运行环境可控的后台服务。

Windows平台使用API枚举盘符与查询空间

Windows没有统一的挂载表文件,取而代之的是盘符概念和挂载点卷(mounted volume)。最基础的枚举方式是调用GetLogicalDriveStringsW,它返回一串以双空字符结尾的盘符字符串,比如C:、D:。遍历这个缓冲区就能拿到所有逻辑驱动器。随后对每个盘符调用GetDiskFreeSpaceExW,可以分别得到用户可用字节、总空闲字节和总字节数,这个函数会自动处理配额限制,比老的GetDiskFreeSpace更可靠。

如果程序需要支持NTFS的目录挂载点(即把卷挂到某个文件夹而非盘符),则要使用FindFirstVolumeMountPointW等卷管理API,逻辑明显复杂。多数桌面工具只关心盘符级空间,因此下面代码演示了最常见的盘符枚举与空间获取:

#include <windows.h>
#include <iostream>

int main() {
    WCHAR buf[256];
    DWORD len = GetLogicalDriveStringsW(255, buf);
    WCHAR* drive = buf;
    while (*drive) {
        ULARGE_INTEGER freeBytes, totalBytes, totalFree;
        if (GetDiskFreeSpaceExW(drive, &freeBytes, &totalBytes, &totalFree)) {
            std::wcout << drive << L" free:" << freeBytes.QuadPart << std::endl;
        }
        drive += wcslen(drive) + 1;
    }
    return 0;
}

上述代码使用宽字符接口,能正确处理中文路径。需要注意GetLogicalDriveStringsW返回的字符串末尾带反斜杠,直接传给目录遍历函数通常没问题,但若拼接其他路径要防止出现双斜杠。Windows API错误码可通过GetLastError区分权限不足与设备未就绪,比如可移动磁盘被拔出时会返回ERROR_NOT_READY。

相比Linux,Windows原生接口更偏向COM和Win32两套体系,如果未来要拿卷GUID或挂载目录,需要引入FindVolumeMountPoint相关调用,代码量会上升。很多团队为了统一跨平台逻辑,会选择封装一层抽象,把两种系统差异隐藏在内部实现后。

使用C++标准库与Boost简化空间统计实战

C++17在<filesystem>中引入了std::filesystem::space函数,它接收一个路径,返回struct space_info,包含capacity、free和available三个字段。available代表普通用户可用的空间,通常比free略小,因为系统会保留一部分给管理员。这个接口在Linux下调statvfs,在Windows下调GetDiskFreeSpaceEx,开发者无需写条件编译。但要注意,标准库并不提供枚举挂载点的能力,只能对已知路径查询,因此挂载点列表仍需平台相关代码补充。

Boost.FileSystem在早期C++11项目中常被使用,其boost::filesystem::space接口与标准库几乎一致,且支持老编译器。若项目已依赖Boost,可顺带用boost::process或系统调用封装去读挂载信息。下面展示标准库查询空间的简洁写法:

#include <filesystem>
#include <iostream>

namespace fs = std::filesystem;

int main() {
    fs::path p = "/";
    std::error_code ec;
    auto info = fs::space(p, ec);
    if (!ec) {
        std::cout << "capacity:" << info.capacity
                  << " free:" << info.free << std::endl;
    }
    return 0;
}

在实战架构里,推荐把平台相关的挂载点扫描单独放在一个源文件中,通过抽象接口暴露vector<MountInfo>,而空间统计统一走std::filesystem::space。这样单元测试时可以用伪挂载列表验证业务逻辑,不必真的依赖操作系统。若需要图形界面展示,还可以把剩余空间换算成GB并标记告警阈值。

最后提醒,无论用哪套方案,都要处理权限错误和异步卸载。比如U盘在查询过程中被拔出,Linux的statvfs会返回错误,Windows会报设备未就绪,程序应捕获异常或错误码,避免崩溃。把挂载点与空间信息封装成带时间戳的缓存结构,也能减少频繁系统调用带来的开销。

C++mount_pointdisk_space修改时间:2026-08-15 02:48:34

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。