【问题标题】:How do I programmatically get the free disk space for a directory in Linux如何以编程方式获取 Linux 中目录的可用磁盘空间
【发布时间】:2011-04-28 21:01:20
【问题描述】:

是否有一个函数可以返回给定目录路径的驱动器分区上有多少可用空间?

【问题讨论】:

    标签: c++ linux


    【解决方案1】:

    查看man statvfs(2)

    我相信您可以将“可用空间”计算为f_bsize * f_bfree

    NAME
           statvfs, fstatvfs - get file system statistics
    
    SYNOPSIS
           #include <sys/statvfs.h>
    
           int statvfs(const char *path, struct statvfs *buf);
           int fstatvfs(int fd, struct statvfs *buf);
    
    DESCRIPTION
           The function statvfs() returns information about a mounted file system.
           path is the pathname of any file within the mounted file  system.   buf
           is a pointer to a statvfs structure defined approximately as follows:
    
               struct statvfs {
                   unsigned long  f_bsize;    /* file system block size */
                   unsigned long  f_frsize;   /* fragment size */
                   fsblkcnt_t     f_blocks;   /* size of fs in f_frsize units */
                   fsblkcnt_t     f_bfree;    /* # free blocks */
                   fsblkcnt_t     f_bavail;   /* # free blocks for unprivileged users */
                   fsfilcnt_t     f_files;    /* # inodes */
                   fsfilcnt_t     f_ffree;    /* # free inodes */
                   fsfilcnt_t     f_favail;   /* # free inodes for unprivileged users */
                   unsigned long  f_fsid;     /* file system ID */
                   unsigned long  f_flag;     /* mount flags */
                   unsigned long  f_namemax;  /* maximum filename length */
               };
    

    【讨论】:

    • 这看起来正是我所需要的。干杯!
    • statvfs 似乎不适用于 vfat 安装的驱动器。我尝试使用 FAT 32 分区,它为可用块提供 0。有办法解决吗?
    • @ShadmanAnwer 不幸的是,手册页上写着:It is unspecified whether all members of the returned struct have meaningful values on all file systems. 所以在这种情况下可能不支持 FAT32。
    • 使用f_bsize * f_bavail 使数据与df -h 命令一致。
    • f_bfree 和 f_bavail 的区别在于为超级用户保留的块(ext2/3/4 文件系统)。这默认为磁盘的 5%。可以使用 tune2fs 和选项 -r &lt;count&gt;-m &lt;percentage&gt; 更改它。也可以在文件系统创建过程中设置。
    【解决方案2】:

    你可以使用 boost::filesystem:

    struct space_info  // returned by space function
    {
        uintmax_t capacity;
        uintmax_t free; 
        uintmax_t available; // free space available to a non-privileged process
    };
    
    space_info   space(const path& p);
    space_info   space(const path& p, system::error_code& ec);
    

    例子:

    #include <boost/filesystem.hpp>
    using namespace boost::filesystem;
    space_info si = space(".");
    cout << si.available << endl;
    

    返回:space_info 类型的对象。 space_info 对象的值是通过使用 POSIX statvfs() 获得一个 POSIX struct statvfs,然后将其 f_blocks、f_bfree 和 f_bavail 成员乘以其 f_frsize 成员来确定的,并将结果分配给 capacity、free 和分别可用的成员。任何无法确定其值的成员都应设置为-1。

    【讨论】:

      【解决方案3】:

      使用 C++17

      你可以使用std::filesystem::space:

      #include <iostream>  // only needed for screen output
      
      #include <filesystem>
      namespace fs = std::filesystem;
      
      int main()
      {
          fs::space_info tmp = fs::space("/tmp");
      
          std::cout << "Free space: " << tmp.free << '\n'
                    << "Available space: " << tmp.available << '\n';
      }
      

      【讨论】:

      • 这可能需要在您的 Makefile 中添加链接器。我需要-lstdc++fs。见注释here
      【解决方案4】:

      可以使用这样的管道将命令的输出输入到程序中:

      char cmd[]="df -h /path/to/directory" ;
      FILE* apipe = popen(cmd, "r");
      // if the popen succeeds read the commands output into the program with 
      while (  fgets( line, 132 , apipe) )
      {  // handle the readed lines
      } 
      pclose(apipe);
      // -----------------------------------
      

      【讨论】:

      • 打开命令会产生新进程,这可能比 C API 调用慢 500 倍 - 2000 倍。最终,您生成的程序也可能是用 C 编写的,而您正在做很多不必要的工作。
      猜你喜欢
      • 2010-11-26
      • 2019-12-12
      • 2010-11-10
      • 1970-01-01
      • 2012-11-15
      • 1970-01-01
      • 2020-05-03
      • 2016-09-09
      • 2020-10-20
      相关资源
      最近更新 更多