Ubuntu上如何获取分区的可用空间

最近工作需要获取指定磁盘分区的可用空间,在这里记录一下。


网上找的资料一般用的是statvfs获取的,不过这种方案有缺陷,这里先简单介绍一下。

1. 使用statvfs获取

函数原型和入参介绍如下:

cpp 复制代码
int statvfs(const char *path, struct statvfs *buf);
// path:文件系统上的目录,磁盘目录不行,需要传对应磁盘的挂载点
// buf:引用传递的入参,包含查询的结果

statvfs结构体介绍如下:

cpp 复制代码
struct statvfs {
    unsigned long f_bsize;       // 用于执行I/O操作的首选块大小
    unsigned long f_frsize;      // 实际用于计算文件系统容量的块大小
    fsblkcnt_t   f_blocks;      // 文件系统中的总块数
    fsblkcnt_t   f_bfree;       // 空闲块的总数(包括保留给超级用户的块)
    fsblkcnt_t   f_bavail;      // 非超级用户可用的空闲块
    fsfilcnt_t   f_files;       // 文件系统能够创建的最大文件节点(inode)数
    fsfilcnt_t   f_ffree;       // 当前空闲的文件节点数(包括给超级用户的)
    fsfilcnt_t   f_favail;      // 非超级用户可用的自由节点
    unsigned long f_flag;       // 文件系统的挂载标志
    unsigned long f_namemax;    // 最大文件名长度
    // ... 其他成员
};

因此:

空闲空间大小 = f_frsize(块大小)× f_bavail(空闲块数)

代码如下:

cpp 复制代码
float get_partition_available_space(const char* partition) {
    // 1. 首先获取分区的挂载点
    char* mount_point = get_mount_point(partition);
    if (!mount_point) {
        printf("Partition %s is not mounted\n", partition);
        return -1;
    }

    // 2. 使用挂载点获取空间信息
    struct statvfs vfs;
    float available_space = -1;
    
    if (statvfs(mount_point, &vfs) == 0) {
        unsigned long long available = vfs.f_bavail * vfs.f_frsize;
        available_space = available / (1024.0 * 1024.0); // 转换为 MiB
    }

    free(mount_point);
    return available_space;
}

这个办法有一个缺点,就是只能获取挂载的磁盘分区,不挂载的无法获取。

2. 获取未挂载的磁盘可用容量

目前尝试过df等指令,以及libparted库,都无法获取。

临时的解决方案是把未挂载的磁盘挂起来,查看可用容量,查完之后再卸载。

代码如下:

cpp 复制代码
float get_unmounted_partition_space(const char* partition) {
    // 创建临时挂载点
    const char* temp_mount = "/tmp/temp_mount";
    if (mkdir(temp_mount, 0755) != 0 && errno != EEXIST) {
        perror("mkdir");
        return -1;
    }
    
    // 临时挂载
    char cmd[256];
    snprintf(cmd, sizeof(cmd), "mount %s %s", partition, temp_mount);
    if (system(cmd) != 0) {
        rmdir(temp_mount);
        return -1;
    }
    
    // 获取空间信息
    struct statvfs vfs;
    float available_space = -1;
    
    if (statvfs(temp_mount, &vfs) == 0) {
        unsigned long long available = vfs.f_bavail * vfs.f_frsize;
        available_space = available / (1024.0 * 1024.0); // 转换为 MiB
    }
    
    // 清理
    snprintf(cmd, sizeof(cmd), "umount %s", temp_mount);
    system(cmd);
    rmdir(temp_mount);
    
    return available_space;
}

这份代码执行需要root权限,因为涉及到挂载和卸载。

相关推荐
木卫二号Coding5 小时前
推荐Linux统计文件大小并操作删除工具-ncdu
linux·运维·服务器
志栋智能6 小时前
超自动化运维:实现IT服务消费化的基础
运维·自动化
198******126346 小时前
2026企业AI办公工具选型指南:从评估框架到场景适配
大数据·运维·人工智能
吴声子夜歌6 小时前
Nginx应用与运维——Nginx HTTP模块详解(数据处理功能模块)
运维·nginx·http
zhangrelay7 小时前
机械臂末端规划智能模型的误区演示
linux·笔记·学习·ubuntu·ros2
2601_967212727 小时前
专利型电源轨道系统技术路线对比与选型框架
大数据·运维·网络·经验分享
数字化顾问8 小时前
(138页PPT)流程体系的建设优化与运营(附下载方式)
大数据·运维·人工智能
2601_967287578 小时前
轮胎侧壁上的 91V 是什么意思,负荷指数与速度级别怎么看
运维·服务器·汽车
Ivanqhz9 小时前
正余弦位置编码(Sinusoidal Positional Encoding)
java·linux·数据库
H.莓飛9 小时前
【数据结构】队列
linux·数据结构·centos