zoukankan      html  css  js  c++  java
  • 【转】statfs获得硬盘使用情况 模拟linux命令 df

    原文网址:http://blog.csdn.net/mociml/article/details/5335474

    说明:本文以主要为转载内容,同时加入了我在使用过程中遇到问题对其的修正!!!!!!!!!

    先说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;  /* 文件名的最大长度 */ 
    }; 
    ***************************************************************
    返回说明:   
    成功执行时,返回0。失败返回-1,errno被设为以下的某个值   
      
    EACCES: (statfs())文件或路径名中包含的目录不可访问 
    EBADF : (fstatfs()) 文件描述词无效 
    EFAULT: 内存地址无效 
    EINTR : 操作由信号中断 
    EIO    : 读写出错 
    ELOOP : (statfs())解释路径名过程中存在太多的符号连接 
    ENAMETOOLONG:(statfs()) 路径名太长 
    ENOENT:(statfs()) 文件不存在 
    ENOMEM: 核心内存不足 
    ENOSYS: 文件系统不支持调用 
    ENOTDIR:(statfs())路径名中当作目录的组件并非目录 
    EOVERFLOW:信息溢出
    **********************************************************************
    相关的文件系统类型有:
          ADFS_SUPER_MAGIC      0xadf5
          AFFS_SUPER_MAGIC      0xADFF
          BEFS_SUPER_MAGIC      0x42465331
       BFS_MAGIC             0x1BADFACE
       CIFS_MAGIC_NUMBER     0xFF534D42
       CODA_SUPER_MAGIC      0x73757245
          COH_SUPER_MAGIC       0x012FF7B7
       CRAMFS_MAGIC          0x28cd3d45
          DEVFS_SUPER_MAGIC     0x1373
          EFS_SUPER_MAGIC       0x00414A53
       EXT_SUPER_MAGIC       0x137D
       EXT2_OLD_SUPER_MAGIC 0xEF51
       EXT2_SUPER_MAGIC      0xEF53
       EXT3_SUPER_MAGIC      0xEF53
       HFS_SUPER_MAGIC       0x4244
       HPFS_SUPER_MAGIC      0xF995E849
       HUGETLBFS_MAGIC       0x958458f6
       ISOFS_SUPER_MAGIC     0x9660
       JFFS2_SUPER_MAGIC     0x72b6
       JFS_SUPER_MAGIC       0x3153464a
          MINIX_SUPER_MAGIC     0x137F /* orig. minix */
       MINIX_SUPER_MAGIC2    0x138F /* 30 char minix */
       MINIX2_SUPER_MAGIC    0x2468 /* minix V2 */
          MINIX2_SUPER_MAGIC2   0x2478 /* minix V2, 30 char names */
       MSDOS_SUPER_MAGIC     0x4d44
       NCP_SUPER_MAGIC       0x564c
       NFS_SUPER_MAGIC       0x6969
       NTFS_SB_MAGIC         0x5346544e
       OPENPROM_SUPER_MAGIC 0x9fa1
         PROC_SUPER_MAGIC      0x9fa0
       QNX4_SUPER_MAGIC      0x002f
          REISERFS_SUPER_MAGIC 0x52654973
       ROMFS_MAGIC           0x7275
       SMB_SUPER_MAGIC       0x517B
       SYSV2_SUPER_MAGIC     0x012FF7B6
       SYSV4_SUPER_MAGIC     0x012FF7B5
          TMPFS_MAGIC           0x01021994
       UDF_SUPER_MAGIC       0x15013346
       UFS_MAGIC             0x00011954
        USBDEVICE_SUPER_MAGIC 0x9fa2
       VXFS_SUPER_MAGIC      0xa501FCF5
       XENIX_SUPER_MAGIC     0x012FF7B4
       XFS_SUPER_MAGIC       0x58465342
       _XIAFS_SUPER_MAGIC    0x012FD16D

    **********************************************************************
    statfs结构中可用空间块数有两种f_bfree和 f_bavail,前者是硬盘所有剩余空间,后

    者为非root用户剩余空间,ext3文件系统给root用户分有5%的独享空间,所以这里是不

    同的地方。这里要强调的是每块的大小一般是4K(×这句话错误,不一定都是4k,正确做法是:总大小= sfs.f_blocks×f_bsize,即块数×每块的大小,单位是bytes,也就是要/1024/1024/1024才是GB单位,另外要注意的问题是sfs.f_blocks×f_bsize数据过大溢出,可以sfs.f_blocks/1024×f_bsize/1024=MB单位)。因此,要实现与df结果一致的就得在

    获得块数上乘以4,这样已用、可用、总块数就可以实现。如果还要实现百分比一致,

    那么要注意的是,df命令获得是整数百分比,没有小数,这里使用的进一法,而不是四

    舍五入法。所以在程序里直接+1取整。

                       disk_size = sfs.f_blocks/1024*sfs.f_bsize/1024;//MB总大小

                       avilable =sfs.f_bavail/1024*sfs.f_bsize/1024;//MB可以空间大小

                       double all=sfs.f_blocks - sfs.f_bfree + sfs.f_bavail;

                       if(0!=all)

                       percent = (sfs.f_blocks - sfs.f_bfree ) * 100 / all + 1;可用百分比

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


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

    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$

    /home/work $ df
    Filesystem           1k-blocks      Used Available Use% Mounted on
    /dev/mmc1                19444      9804      9640  50% /boot
    /dev/mmc2                11678        78     11600   1% /setting
    /dev/mmc5               160730    126767     25665  83% /home
    /dev/mmc6              1758860     35492   1634020   2% /storage
    /dev/sdb1            312568828  42536564 270032264  14% /c2-media/usb/USB2

  • 相关阅读:
    参数传递二维数组 .
    类的static成员变量和成员函数能被继承吗
    Oracle面试题(基础篇)
    Visual C++ 8.0对象布局
    C++对象模型 多重继承与虚函数表
    浅析GCC下C++多重继承 & 虚拟继承的对象内存布局
    C++对象内存布局测试总结
    查找
    反转链表
    排序
  • 原文地址:https://www.cnblogs.com/wi100sh/p/4281326.html
Copyright © 2011-2022 走看看