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

相关推荐
chlk12314 小时前
Linux文件权限完全图解:读懂 ls -l 和 chmod 755 背后的秘密
linux·操作系统
舒一笑15 小时前
Ubuntu系统安装CodeX出现问题
linux·后端
改一下配置文件15 小时前
Ubuntu24.04安装NVIDIA驱动完整指南(含Secure Boot解决方案)
linux
碳基沙盒16 小时前
OpenClaw 多 Agent 配置实战指南
运维
深紫色的三北六号1 天前
Linux 服务器磁盘扩容与目录迁移:rsync + bind mount 实现服务无感迁移(无需修改配置)
linux·扩容·服务迁移
SudosuBash1 天前
[CS:APP 3e] 关于对 第 12 章 读/写者的一点思考和题解 (作业 12.19,12.20,12.21)
linux·并发·操作系统(os)
哈基咪怎么可能是AI2 天前
为什么我就想要「线性历史 + Signed Commits」GitHub 却把我当猴耍 🤬🎙️
linux·github
十日十行2 天前
Linux和window共享文件夹
linux
Sinclair2 天前
简单几步,安卓手机秒变服务器,安装 CMS 程序
android·服务器
木心月转码ing3 天前
WSL+Cpp开发环境配置
linux