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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM