【问题标题】:Get Real Free Usable Space获得真正的可用空间
【发布时间】:2013-04-03 20:30:51
【问题描述】:

我遇到了一个程序问题,它应该将任何用户都可以使用的可用磁盘空间发回给我。

我的目标是让没有 sudo 权限的任何人都可以使用我的硬盘驱动器的每个分区的所有可用磁盘空间。

所以我尝试了这个:

int main() {
    struct statvfs diskData;
    statvfs("/", &diskData);
    unsigned long long available = (diskData.f_favail + diskData.f_bavail) * diskData.f_frsize) / (1024 * 1024)
    std::cout << "Free Space : " << available << std::endl;
}

这给了我总共2810 ...

但是,当我输出df -h 时,我可以读到sda3 的可用空间是25Gsda1 的可用空间是30G

这似乎完全不准确。

我一直在 Stackoverflow 上运行帖子,混合我看到的解决方案,但没有一个是令人满意的。我如何才能获得以 MB 为单位的可用可用空间的正确值?

编辑:完整的 statvfsdf / 输出

statvfs

Block Size            : 4 096
Fragment Size         : 4 096
Blocks                : 9 612 197
Free Blocks           : 7 009 166
Non Root Free Blocks  : 6 520 885
Inodes                : 2 444 624
Free Inodes Space     : 2 137 054
Non Root Free Inodes  : 2 137 054
File System ID        : 4 224 884 198
Mount Flags           : 4 096
Max Filename Length   : 255

df /

Filesystem     1K-Blocks      Used           Available      Use%     Mounted on
/dev/sda3      38 448 788     10 412 112     26 083 556     29%      / 

【问题讨论】:

    标签: c++ ubuntu diskspace


    【解决方案1】:

    这似乎是对可用磁盘空间的更准确测量:

    unsigned long long available = (diskData.f_bavail * diskData.f_bsize) / (1024 * 1024);
    

    它在我的系统上与 df 的输出非常匹配(df 以 gig 为单位显示大小,并且可能四舍五入)。

    如果你想要像df 这样的演出,你可以使用这个:

    #include <sys/statvfs.h>
    #include <stdio.h>
    
    unsigned long rounddiv(unsigned long num, unsigned long divisor) {
        return (num + (divisor/2)) / divisor;
    }
    
    int main() {
        struct statvfs diskData;
        statvfs("/home", &diskData);
        unsigned long available = diskData.f_bavail * diskData.f_bsize;
        printf("Free Space : %luG\n", rounddiv(available, 1024*1024*1024));
        return 0;
    }
    

    我系统上的输出:
    Free Space : 31G

    如果我运行df -h /home:

    Filesystem            Size  Used Avail Use% Mounted on
                          181G  141G   31G  83% /home
    

    【讨论】:

    • 嗯,你一定是对的,但是我现在得到了1992 的结果,以及你向我提出的建议。 f_bavail 返回 510 003f_bsize 返回 4096available 在 Gigs of Megs 中吗?因为两者似乎都不再准确......我错过了什么吗?
    • 感谢您的新答案。我认为您的代码一定是正确的,但是我必须有另一个问题,因为当我使用/df -h / 时我输出df -h / 告诉我在/dev/sda3 上(只有安装在/ 上的东西)我得到了25G 可用 ...
    【解决方案2】:

    似乎要使用的正确值是片段大小,而不是块大小(即 f_frsize)

    你试过了吗

    diskData.f_bavail * diskData.f_frsize
    

    不是吗?

    【讨论】:

    • 是的,我认为它更好!但是片段大小和块大小在我的系统上是相同的值。我得到了同样的结果。
    • 您能否使用statvfsdf /(不带-h)的全部输出更新帖子?这会很有帮助。
    • 6 520 885 * 4096 / 1024 得到 26 083 540,这非常接近 df (26 083 556) 的输出。将该值除以 1024*1024 应该可以得到预期的输出。
    • 我猜你使用的是 32 位有符号整数,最多可以表示 2^31-1(大约 2 147 483 647)。 6 520 886 * 4096 等于 26 709 549 056,后者更大。您应该至少使用 64 位整数,或者,如果您的近似值足够,则使用浮点类型。
    • 您必须在进行乘法之前进行转换。例如float f_bavail = diskData.f_bavail; float f_frsize = diskData.f_frsize; float available = f_bavail * f_frsize / (1024 * 1024);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-13
    • 2020-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多