2009-10-10

statfs:

结构:

#include <sys/vfs.h>    /* 或者 <sys/statfs.h> */

int statfs(const char *path, struct statfs *buf);
int fstatfs(int fd, struct statfs *buf);

参数:

`path`: 位于需要查询信息的文件系统的文件路径名。    
`fd`: 位于需要查询信息的文件系统的文件描述词。
`buf`:以下结构体的指针变量,用于储存文件系统相关的信息

struct statfs {
   long    f_type;     /* 文件系统类型  */
   long    f_bsize;    /* 经过优化的传输块大小  */
   long    f_blocks;   /* 文件系统数据块总数 */
   long    f_bfree;    /* 可用块数 */
   long    f_bavail;   /* 非超级用户可获取的块数 */
   long    f_files;    /* 文件结点总数 */
   long    f_ffree;    /* 可用文件结点数 */
   fsid_t  f_fsid;     /* 文件系统标识 */
   long    f_namelen;  /* 文件名的最大长度 */
};

statfs结构中可用空间块数有两种f_bfreef_bavail,前者是硬盘所有剩余空间,后者为非root用户剩余空间,ext3文件系统给root用户分有5%的独享空间,所以这里是不同的地方。这里要强调的是每块的大小一般是4K。因此,要实现与df结果一致的就得在获得块数上乘以4,这样已用、可用、总块数就可以实现。如果还要实现百分比一致,那么要注意的是,df命令获得是整数百分比,没有小数,这里使用的进一法,而不是四舍五入法。所以在程序里直接+1取整。

下面是实现的一个例子:(home目录为一个独立分区) #include #include

int main()
{
    struct statfs sfs;
    int i = statfs("/home", &sfs);
    int percent = (sfs.f_blocks - sfs.f_bfree ) * 100 / (sfs.f_blocks - sfs.f_bfree + sfs.f_bavail) + 1;
    printf("/dev/sda11            %ld    %ld  %ld   %d%% /home\n",
                           4*sfs. f_blocks, 4*(sfs.f_blocks - sfs.f_bfree),      4*sfs.f_bavail, percent);
    system("df /home ");
    return 0;

}

执行结果:

leave@LEAVE:~/test$ gcc -o df df.c
leave@LEAVE:~/test$ ./df
/dev/sda11            42773008    540356  40059864   2% /home
文件系统           1K-块        已用     可用 已用% 挂载点
/dev/sda11            42773008    540356  40059864   2% /home
leave@LEAVE:~/test$

-----------------------------------------busybox 中使用的挂载分区获取使用率-----------------------------

#include <stdio.h>
#include <sys/vfs.h>

#include <string.h>


extern int get_free_rate(char *path)
{
 struct statfs str_diskatr;
 long blocks_percent_used=0;
 long blocks_used=0;
 memset( &str_diskatr, 0x00, sizeof(str_diskatr) );

 if ( 0x00 == statfs( path, &str_diskatr ) )
 {
  if ( (str_diskatr.f_blocks != 0x00) ){
   blocks_used = str_diskatr.f_blocks - str_diskatr.f_bfree;
   blocks_percent_used = (((long long) blocks_used) * 100
     + (blocks_used + str_diskatr.f_bavail)/2
     ) / (blocks_used + str_diskatr.f_bavail);
   return blocks_percent_used;
  }
  else
   return -1;
 }
 else if(-1 == statfs( path, &str_diskatr ))
 {
  if(errno == ENOENT)
  {
   return 0;
  }
 }
 else
 {return -1;}

 return -1;
}

上面程序裁剪自busybox,使用

#define IDEDIR  "/mnt/ide/"   //挂载目录

(int )ide_useage = get_free_rate(IDEDIR);

----------------------------------计算文件夹占用空间大小-----------------------------------------------

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>

static unsigned int total = 0;

int sum(const char *fpath, const struct stat *sb, int typeflag)
{

    total += sb->st_size;
    return 0;

}


int main(int argc, char **argv)
{

    if (!argv[1] || access(argv[1], R_OK)) {

        return 1;

    }

    if (ftw(argv[1], &sum, 1)) {

        perror("ftw");

        return 2;

    }

    printf("%s: %u\n", argv[1], total);

    return 0;

}

执行结果:

lm@LM:/home/lm/tmpfs/c_c++> gcc -o du  du.c            11-03-24 10:06
lm@LM:/home/lm/tmpfs/c_c++> ./du /home/lm/音乐         11-03-24 10:22
/home/lm/音乐: 726629477
lm@LM:/home/lm/tmpfs/c_c++>                            11-03-24 10:22
  • (2010.6.29修正 添加busybox中的系统算法)
  • (2011.3.24修正 添加获取文件夹的大小)


blog comments powered by Disqus