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权限,因为涉及到挂载和卸载。

相关推荐
liguojun20251 分钟前
篮球馆自动计时收费系统:从规则配置到自动结算的全流程拆解
java·大数据·运维·人工智能·物联网·1024程序员节
Promise微笑21 分钟前
红外分辨率 160×120、320×240、384×288 与 640×480实战选型指南
大数据·运维·人工智能·物联网
顾喵1 小时前
PetaLinux 2017.4 实操指南:PREEMPT_RT实时补丁移植+Zynq PL中断UIO用户态配置(超完整避坑版)
linux
小樱花的樱花1 小时前
Linux 线程的创建
linux·c语言·开发语言
云飞云共享云桌面1 小时前
单机建模卡顿运维繁琐!中小型机械制造厂云飞云 3D 云桌面落地
运维·服务器·网络·3d·自动化·电脑·负载均衡
mounter6252 小时前
BPF 的进化史:从网络过滤器到 AI 时代的 Linux 核心引擎
linux·网络·人工智能·ebpf·linux kernel·kernel
zandy10112 小时前
体验家 XMPlus 批量操作与自动化工作流引擎:让大规模运营从手动执行走向规则驱动
大数据·运维·自动化
湿韵轮回3 小时前
LangChain LCEL,用 | 串联AI的魔法语言
服务器·人工智能·langchain
Sagittarius_A*3 小时前
Docker:渗透前置容器化核心基础
运维·安全·docker·容器
网络小白不怕黑4 小时前
监控httpd状态
服务器