当前位置: 首页 > 面试题库 >

正确将statvfs转换为可用百分比

喻珂
2023-03-14
问题内容

我有一个非常简单的测试程序,可以打印出以下数字。

int main(int argc, char* argv[])
  struct statvfs vfs;
  statvfs(argv[1], &vfs);
  printf("f_bsize (block size): %lu\n"
       "f_frsize (fragment size): %lu\n"
       "f_blocks (size of fs in f_frsize units): %lu\n"
       "f_bfree (free blocks): %lu\n"
       "f_bavail free blocks for unprivileged users): %lu\n"
       "f_files (inodes): %lu\n"
       "f_ffree (free inodes): %lu\n"
       "f_favail (free inodes for unprivileged users): %lu\n"
       "f_fsid (file system ID): %lu\n"
       "f_flag (mount flags): %lu\n"
       "f_namemax (maximum filename length)%lu\n",
       vfs.f_bsize,
       vfs.f_frsize,
       vfs.f_blocks,
       vfs.f_bfree,
       vfs.f_bavail,
       vfs.f_files,
       vfs.f_ffree,
       vfs.f_favail,
       vfs.f_fsid,
       vfs.f_flag,
       vfs.f_namemax);

       return 0;
    }

打印输出:

f_bsize (block size): 4096
f_frsize (fragment size): 4096
f_blocks (size of fs in f_frsize units): 10534466
f_bfree (free blocks): 6994546
f_bavail free blocks for unprivileged users): 6459417
f_files (inodes): 2678784
f_ffree (free inodes): 2402069
f_favail (free inodes for unprivileged users): 2402069
f_fsid (file system ID): 12719298601114463092
f_flag (mount flags): 4096
f_namemax (maximum filename length)255

df输出根fs:

Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/sda5             42137864  14159676  25837672  36% /

但是,这是我感到困惑的地方。

25837672 + 14159676!= 42137846(实际上是39997348)

因此,如果我要执行calc 14159676/42137864 * 100,我得到的df打印结果为33%,而不是36%。

但是如果我计算

14159676/39997348 * 100我得到了35%。

为什么所有差异以及df在哪里获得编号42137864?这与到1k块的转换与4k的实际系统块大小有关吗?

这将集成到我的缓存应用程序中,以告诉我驱动器何时处于某个阈值…例如90%,然后再开始释放固定大小为2 ^
n大小的固定大小的块。因此,我需要的是一个可以给我合理准确的使用率的函数。

编辑:我现在可以匹配什么df打印。除了已使用的百分比。这使我们想知道这一切有多精确。片段大小是多少?

unsigned long total = vfs.f_blocks * vfs.f_frsize / 1024;
unsigned long available = vfs.f_bavail * vfs.f_frsize / 1024;
unsigned long free = vfs.f_bfree * vfs.f_frsize / 1024;

printf("Total: %luK\n", total);
printf("Available: %luK\n", available);
printf("Used: %luK\n", total - free);

编辑2:

unsigned long total = vfs.f_blocks * vfs.f_frsize / 1024;
unsigned long available = vfs.f_bavail * vfs.f_frsize / 1024;
unsigned long free = vfs.f_bfree * vfs.f_frsize / 1024;
unsigned long used = total - free;

printf("Total: %luK\n", total);
printf("Available: %luK\n", available);
printf("Used: %luK\n", used);
printf("Free: %luK\n", free);

// Calculate % used based on f_bavail not f_bfree.  This is still giving out a different answer to df???
printf("Use%%: %f%%\n",  (vfs.f_blocks - vfs.f_bavail) / (double)(vfs.f_blocks) * 100.0);

f_bsize (block size): 4096
f_frsize (fragment size): 4096
f_blocks (size of fs in f_frsize units): 10534466
f_bfree (free blocks): 6994182
f_bavail (free blocks for unprivileged users): 6459053
f_files (inodes): 2678784
f_ffree (free inodes): 2402056
f_favail (free inodes for unprivileged users): 2402056
f_fsid (file system ID): 12719298601114463092
f_flag (mount flags): 4096
f_namemax (maximum filename length)255
Total: 42137864K
Available: 25836212K
Used: 14161136K
Free: 27976728K
Use%: 38.686470%

matth@kubuntu:~/dev$ df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/sda5             42137864  14161136  25836212  36% /

我得到38%而不是36。如果用f_bfree计算,我得到33%。df是错误的,还是永远不会是准确的?如果是这种情况,那么我想靠保守一点。


问题答案:

df的数据可能基于而f_bavail不是f_bfree。您可能会发现查看df的源代码以了解其工作方式很有帮助。它有许多需要处理的极端情况(例如,当使用的空间超出了非root用户可用的空间量时),但是正常情况的相关代码如下:

  uintmax_t u100 = used * 100;
  uintmax_t nonroot_total = used + available;
  pct = u100 / nonroot_total + (u100 % nonroot_total != 0);

换句话说100 * used / (used + available),四舍五入。插入df输出中的值,得到100 * 14159676 / (14159676 + 25837672) = 35.4015371,舍入为36%,与df计算得出的一样。



 类似资料:
  • 问题内容: 我正在寻找python库或任何将.XLSX文件转换为.CSV文件的帮助。 问题答案: 使用该模块阅读excel ,然后可以使用该模块创建自己的csv。 在命令行中安装xlrd模块: Python脚本:

  • 问题内容: 有没有一种方法可以将os.cpus()信息转换为百分比?就像iostat的输出(在CPU部分)一样。 我的代码: 输出: 我想将“时间”指标转换为百分比,就像在命令上显示的一样: 我知道nodejs函数中的值以CPU滴答为单位,但是我不知道应该使用什么公式将它们转换为百分比:) 谢谢。 问题答案: 根据该文档,是 包含花费在其中的CPU滴答声数量的对象:user,nice,sys,id

  • 我有一个本机方法,它返回目录中的文件数组。公共静态本机字符[][]扫描(字符串路径);我不能返回字符串数组,因为如果文件的编码无效-一切都崩溃了,问题是在java端正确地将char[]转换为字符串,当我尝试新字符串(chars)时;我得到无法打印的字符串(无效)。请纠正我。 这是输出的示例(如果方法返回String[])

  • 自从我尝试模拟我的客户端和服务器之间处理数据包的连接以来,我一直在与字节数组和BigIntger进行斗争。 当我的客户端连接到服务器时,服务器发送了一个包含RSA公钥的响应,然后是一个十六进制数据包,如下所示: C70001A1004080之后的64字节是RSA公共指数。RSA指数后的128字节是模数。 然后我尝试提取指数和模来重新生成RSA公钥。我的步骤: 最后我有了一个公钥: 与服务器上的RS

  • 问题内容: 我知道如何获取mysql行并将其转换为json: 但: 数据库行具有不同的类型,例如int,float,string。通过使用json_encode()进行转换,所有结果都是字符串。 有没有比这更好的方法来更正类型: 我想遍历键并添加0,因为: 第一个编码规则:干-不要重复自己 但我不能,因为: 行还具有数字以外的其他类型(字符串,日期) 有很多列 设计在开发人员中,因此列名经常更改

  • 我有一个关于合同管理的web应用程序,带有React和SpringBoot。用户应该能够添加新合同,然后将合同下载为PDF文件,这样他就可以签署合同,然后上传合同。pdf签名。我使用java中的多部分文件进行上传和下载,并将PDF存储在MySql数据库中。 PDF是在SpringBoot服务器中用Thymeleaf从HTML文件创建的。我不清楚的是如何将PDF文件转换为MultipartFile,