You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何计算磁盘使用率以匹配df命令的Use%输出?

Rust计算磁盘使用率与df命令结果不一致的解决思路

你遇到的问题核心是statvfs字段含义的理解偏差以及df命令的计算逻辑和你代码里的逻辑不一致,下面拆解原因并给出修正方案:

问题根源解析

  1. 已用空间计算错误:
    你代码里用total_space - blocks_available()得到的"已用空间",其实是已用空间+root用户预留的空间。因为statvfs的blocks_available()返回的是普通用户可使用的空闲块数,而blocks_free()才是文件系统的总空闲块数(包含root预留的不可被普通用户访问的空间)。df命令的Used字段正是用Total - Free(Free对应blocks_free())计算出来的。

  2. 使用率计算逻辑不一致:
    df的Use%并不是简单的Used/Total*100,而是Used/(Used+Available)*100——这里的Available是普通用户可用空间(对应blocks_available()),分母是实际可分配的空间总和(已用+普通用户可用),排除了root预留的那部分不可用空间。

看你的示例数据就能验证:

  • 总空间:6779424768
  • df的Used:2713636864 = 总空间 - 总空闲空间(6779424768 - 4065787904)
  • 你代码里的Used:3081613312 = 总空间 - 普通用户可用空间(6779424768 - 3697811456)
  • 两者的差值正好是root预留的空间:3081613312 - 2713636864 = 367976448

修正后的代码

use nix::sys::statvfs::statvfs;
macro_rules! cast { ($x:expr) => { u64::from($x) }; }
fn main() {
    let stat = statvfs("/var/db".as_bytes()).unwrap();
    
    // 总空间:和df的1B-blocks完全一致
    let total_space = cast!(stat.block_size()) * cast!(stat.blocks());
    // 总空闲空间(包含root预留):对应df里的Total - Used
    let free_space = cast!(stat.block_size()) * cast!(stat.blocks_free());
    // df的Used字段:总空间 - 总空闲空间
    let used_space = total_space - free_space;
    // df的Available字段:普通用户可使用的空闲空间
    let avail_space = cast!(stat.block_size()) * cast!(stat.blocks_available());
    
    // 对齐df的使用率计算逻辑:Used / (Used + Available) * 100
    let usage = used_space * 100 / (used_space + avail_space);
    
    println!("total: {}", total_space);
    println!("avail: {}", avail_space);
    println!("used: {}", used_space);
    println!("use%: {}%", usage);
}

关键字段说明

再明确下statvfs几个核心字段的含义,避免再踩坑:

  • blocks():文件系统的总块数
  • blocks_free():文件系统的总空闲块数(包含root用户专属的预留块)
  • blocks_available():普通用户可访问的空闲块数(排除root预留)
  • block_size():文件系统的基础块大小,用来将块数转换为字节数

运行修正后的代码,你会得到和df命令完全一致的结果啦。

内容的提问来源于stack exchange,提问作者nbari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:28:15