zoukankan      html  css  js  c++  java
  • stat(),lstat(),fstat() 获取文件/目录的相关信息

     

     

    stat 的使用

    Linux有个命令,ls -l,效果如下:

     

    这个命令能显示文件的类型、操作权限、硬链接数量、属主、所属组、大小、修改时间、文件名。它是怎么获得这些信息的呢,请看下面的讲解。

    stat 的基本使用

    stat:返回一个与此命

    需要包含的头文件: <sys/types.h>,<sys/stat.h>,<unistd.h>

    函数原型:

      int stat(const char *path, struct stat *buf);
          int fstat(int fd, struct stat *buf);
          int lstat(const char *path, struct stat *buf);

    参数:

      对于stat() & lstat()来说path,是要查看属性的文件或目录的全路径名称

      对于fstat,fd 是要查看属性文件的文件描述符

      buf:指向用于存放文件属性的结构体,函数成功调用后,buf各个字段存放各个属性。

    返回值 成:

      功返回0;      错误返回 -1;

    给定一个文件:

      stat 函数获得一个与此命名文件有关的信息(到一个struct stat 类型的buf中) 。

      fstat 函数获得文件描述符 fd 打开文件的相关信息(到一个struct stat 类型的buf中) 。

      lstat 函数类似于 stat,但是当命名文件是一个符号连接时, lstat 获取该符号连接的有关信息,而不是由该符号连接引用文件的信息。

    struct stat在系统头文件<stat.h>中,具体定义如下:

     1 struct stat     
     2 {     
     3     dev_t       st_dev;     /* ID of device containing file -文件所在设备的ID*/     
     4     ino_t       st_ino;     /* inode number -inode节点号*/   
     5     mode_t      st_mode;    /* Protection -文件的类型和存取的权限*/     
     6     nlink_t     st_nlink;   /* number of hard links -链向此文件的连接数(硬连接)*/     
     7     uid_t       st_uid;     /* user ID of owner -user id*/     
     8     gid_t       st_gid;     /* group ID of owner - group id*/     
     9     dev_t       st_rdev;    /* device ID (if special file) -设备号,针对设备文件*/     
    10     off_t       st_size;    /* total size, in bytes -文件大小,字节为单位*/     
    11     blksize_t   st_blksize; /* blocksize for filesystem I/O -系统块的大小*/     12     blkcnt_t    st_blocks;  /* number of blocks allocated -文件所占块数*/     
    13     time_t      st_atime;   /* time of last access -最近存取时间*/     
    14     time_t      st_mtime;   /* time of last modification -最近修改时间*/     
    15     time_t      st_ctime;   /* time of last status change - */     
    16 };  

    st_mode是用特征位来表示文件类型以及操作权限的,特征位的定义如下:

     1 S_IFMT      0170000     文件类型的位遮罩
     2 S_IFSOCK    0140000     socket
     3 S_IFLNK     0120000     符号链接(symbolic link)
     4 S_IFREG     0100000     一般文件
     5 S_IFBLK     0060000     区块装置(block device)
     6 S_IFDIR     0040000     目录
     7 S_IFCHR     0020000     字符装置(character device)
     8 S_IFIFO     0010000     先进先出(fifo)
     9 S_ISUID     0004000     文件的(set user-id on execution)位
    10 S_ISGID     0002000     文件的(set group-id on execution)位
    11 S_ISVTX     0001000     文件的sticky位
    12 S_IRWXU     00700       文件所有者的遮罩值(即所有权限值)
    13 S_IRUSR     00400       文件所有者具可读取权限
    14 S_IWUSR     00200       文件所有者具可写入权限
    15 S_IXUSR     00100       文件所有者具可执行权限
    16 S_IRWXG     00070       用户组的遮罩值(即所有权限值)
    17 S_IRGRP     00040       用户组具可读取权限
    18 S_IWGRP     00020       用户组具可写入权限
    19 S_IXGRP     00010       用户组具可执行权限
    20 S_IRWXO     00007       其他用户的遮罩值(即所有权限值)
    21 S_IROTH     00004       其他用户具可读取权限
    22 S_IWOTH     00002       其他用户具可写入权限
    23 S_IXOTH     00001       其他用户具可执行权限
    

     POSIX定义了下面几种通过st_mode判断文件类型的宏:

    1 The following POSIX macros are defined to check the file type using the st_mode field:
    2 S_ISREG(m)  /* is it a regular file? -普通文件 */
    3 S_ISDIR(m)  /* directory? -目录文件? */
    4 S_ISCHR(m)  /* character device? -字符设备文件? */
    5 S_ISBLK(m)  /* block device? -块设备文件? */
    6 S_ISFIFO(m) /* FIFO (named pipe)? -管道文件? */
    7 S_ISLNK(m)  /* symbolic link? (Not in POSIX.1-1996.) -符号链接? */
    8 S_ISSOCK(m) /* socket? (Not in POSIX.1-1996.) -套接口? */

    1. stat()获取文件相关信息

     1 #include <stdio.h> 
     2 #include <stat.h>
     3 #include <sys/types.h>
     4 #include <sys/stat.h>
     5 #include <unistd.h>
     6  
     7 int main(int argc, char **argv)
     8 {
     9     struct stat     buf;
    10     if(argc != 2) { 
    11        printf("Usage: stat "); 
    12        exit(-1); 
    13     }
    14     if(stat(argv[1], &buf) != 0) { 
    15         printf("stat error."); 
    16         exit(-1); 
    17     }
    18     printf("#i-node:    %ld
    ", buf.st_ino);
    19     printf("#link:      %d
    ", buf.st_nlink);
    20     printf("UID:        %d
    ", buf.st_uid);
    21     printf("GID:        %d
    ", buf.st_gid);
    22     printf("Size        %ld
    ", buf.st_size);
    23     exit(0);
    24 }

    2. 实现Linux ls命令

     1 #include <stdio.h>
     2 #include <dirent.h>
     3 #include <sys/types.h>
     4 #include <sys/stat.h>
     5 #include <unistd.h>
     6 #include <pwd.h>
     7 #include <grp.h>
     8 #include <time.h>
     9 #include <string.h>
    10 
    11 char gettype(mode_t mod)
    12 {
    13     /*
    14        if( S_ISREG(mod) ) return '-';
    15        if( S_ISDIR(mod) ) return 'd';
    16        if( S_ISCHR(mod) ) return 'c';
    17        if( S_ISBLK(mod) ) return 'b';
    18        if( S_ISLNK(mod) ) return 'l';
    19        if( S_ISSOCK(mod) ) return 's';
    20        if( S_ISFIFO(mod) ) return 'p';
    21        */
    22     switch(mod & S_IFMT)
    23     {
    24     case S_IFSOCK: return 's';
    25     case S_IFREG: return '-';
    26     case S_IFCHR: return 'c';
    27     case S_IFBLK: return 'b';
    28     case S_IFLNK: return 'l';
    29     case S_IFIFO: return 'p';
    30     case S_IFDIR: return 'd';
    31     }
    32 }
    33 
    34 char *getperm(mode_t mod)
    35 {
    36     static char buf[10];
    37 
    38     int i = 9;
    39     while(i--)
    40     {
    41         if(mod & 1<<i)
    42         {
    43             switch((8-i)%3)
    44             {
    45             case 0: buf[8-i] = 'r'; break;// r/w/x;
    46             case 1: buf[8-i] = 'w'; break;// r/w/x;
    47             case 2: buf[8-i] = 'x'; break;// r/w/x;
    48             }
    49         }
    50         else
    51             buf[8-i] = '-';
    52     }
    53 
    54     return buf;
    55 }
    56 
    57 char *getttt(time_t *t)
    58 {
    59     static char buf[50];
    60 
    61     strncpy(buf, ctime(t), 24);
    62 
    63     return buf;
    64 }
    65 
    66 int main(int argc, char **argv)
    67 {
    68     DIR *dp = opendir((2==argc)?argv[1]:"."); 
    69 
    70     if(2 == argc)
    71         chdir(argv[1]);
    72 
    73     struct dirent *p;
    74 
    75     struct stat s;
    76     while( p = readdir(dp) )
    77     {
    78         if(-1 == stat(p->d_name, &s) )
    79         {
    80             perror("stat");
    81             return -1;
    82         }
    83 
    84         printf( "%c%s %5d %s %s %10ld %s33[1;31;40m %s  33[0m
    ", 
    85                 gettype(s.st_mode),
    86                 getperm(s.st_mode),
    87                 s.st_nlink,
    88                 getpwuid(s.st_uid)->pw_name,
    89                 getgrgid(s.st_gid)->gr_name,
    90                 s.st_size, 
    91                 getttt(&s.st_mtime),
    92                 p->d_name );
    93     }
    94 }
  • 相关阅读:
    第四节 哈希类型
    第三节 string类型
    第二节 redis的数据类型和一些通用的键命令
    第一节 Redis的安装配置
    第三十二节 定时器
    第三十一节 sed命令
    第三十节 awk命令
    第二十九节 cut命令
    第二十八节 函数和脚本调试
    Gartner 如何看 RASP 和 WAF?
  • 原文地址:https://www.cnblogs.com/chen-farsight/p/6023757.html
Copyright © 2011-2022 走看看