首页 > 代码库 > Stat(),Lstat(),Fstat() 获取文件/目录的相关信息

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\n", buf.st_ino);
19     printf("#link:      %d\n", buf.st_nlink);
20     printf("UID:        %d\n", buf.st_uid);
21     printf("GID:        %d\n", buf.st_gid);
22     printf("Size        %ld\n", 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 %s\033[1;31;40m %s  \033[0m\n", 
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 }

 

Stat(),Lstat(),Fstat() 获取文件/目录的相关信息