Linux学习:文件属性函数
1、stat 命令
stat filename ,功能上類似于 ls - l。
2、stat 函數
(1)頭文件:
#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>(2)原型:
int stat(const char *pathname, struct stat *buf);(3)參數:
1)pathname :文件名稱(包含路徑,不寫默認當前目錄下)。
2)buf : 結構體:結構體元素為文件信息。
(4)返回值:
成功返回 0; 失敗返回 -1,設置 erron 。
3、使用 stat 函數獲得文件大小
struct stat st; int ret = stat(“bigtext.txt”, &st); if(ret == -1){ perror(“stat error”); exit(1); } printf(“file size = %d\n”, (int)st.st_size); // 注意類型強轉,否則編譯有警告4、使用 stat 函數獲得文件類型和權限
對應結構體中的元素是 mode_t 和st_mode。
類型:
(1)mode_t (本質是一個 16 位的整數,也稱位圖)。
(2)st_mode :16 位整數,分 5 塊(特殊權限位不需要掌握),如下圖所示:
(1)0-2 bit :其他人權限
1)宏:S_IROTH ;八進制數:0004 ;權限:讀權限。
2)宏:S_IWOTH ;八進制數:0002 ;權限:寫權限 。
3)宏:S_IXOTH ;八進制數:0001 ;權限:執行權限 。
(2) 3-5 bit :所屬組權限
1)宏:S_IRGRP;八進制數: 0040 ;權限:讀權限 。
2)宏:S_IWGRP ;八進制數:0020 ;權限:寫權限。
3)宏: S_IXGRP ;八進制數:0010 ;權限:執行權限。
(3) 6-8 bit : 文件所有者權限
1)S_IRUSR ;0400 ;讀權限。
2)S_IWUSR ;0200; 寫權限。
3)S_IXUSR ;0100; 執行權限。
(4)12-15 bit :文件類型
1)S_IFSOCK ;140000 ;套接字 。
2)S_IFLNK ;120000; 符號連接(軟鏈接)。
3)S_IFREG ;100000 ;普通文件。
4)S_IFBLK ;060000 ;塊設備。
5)S_IFDIR ;040000; 目錄。
6)S_IFCHR ;020000; 字符設備。
7)S_IFIFO ;010000 ;管道。
8)S_IFMT ;170000; 掩碼。
5、stat 、 lstat 、fstat 的 區別
int stat(const char *pathname, struct stat *buf); int lstat(const char *pathname, struct stat *buf); // 前兩個函數形式基本一樣 int fstat(int fd, struct stat *buf);主要是在查看軟鏈接文件時候有區別:
(1)stat 是 讀取“軟鏈接指向的文件”的屬性 (穿透軟鏈接)。
(2)lstat 是 讀取“軟鏈接本身文件”的屬性(不穿透軟鏈接)。
(3)fstat 是使用 open 打開文件后,通過文件描述符讀取文件屬性。
6、實現 ls -l filename
代碼如下:
#include <stdio.h> #include <unistd.h> #include <sys/stat.h> #include <string.h> #include <pwd.h> #include <grp.h> #include <time.h> int main(int argc, char *argv[]) {if(argc < 2){ perror("./a.out filename\n");return -1;}struct stat sb ; if( lstat(argv[1], &sb ) < 0 ) // 函數調用失敗,打印錯誤信息,否則不執行if,表示獲得信息成功 {perror("stat err"); return -1; } // 代碼執行到這個位置,意味著獲得信息成功char fileMode[11] = {0}; // 比如 drwxr-xr-x 字符串 共10位+ \0 memset( fileMode, '-', 10); // 最后一位不格式//先搞定文件類型if(S_ISREG(sb.st_mode)) fileMode[0] = '-'; // regular fileif(S_ISDIR(sb.st_mode)) fileMode[0] = 'd'; // directoryif(S_ISCHR(sb.st_mode)) fileMode[0] = 'c'; // character deviceif(S_ISBLK(sb.st_mode)) fileMode[0] = 'b'; // block deviceif(S_ISFIFO(sb.st_mode)) fileMode[0] = 'p'; // FIFO (named pipe)if(S_ISLNK(sb.st_mode)) fileMode[0] = 'l'; // symbolic linkif(S_ISSOCK(sb.st_mode)) fileMode[0] = 's'; // socket//在搞定三類用戶的權限//用戶if(S_IRUSR & sb.st_mode) fileMode[1] = 'r'; // 否則因為memset ,默認是 ’-’if(S_IWUSR & sb.st_mode) fileMode[2] = 'w';if(S_IXUSR & sb.st_mode) fileMode[3] = 'x';//組用戶if(S_IRGRP & sb.st_mode) fileMode[4 ]= 'r';if(S_IWGRP & sb.st_mode) fileMode[5] = 'w';if(S_IXGRP & sb.st_mode) fileMode[6] = 'x';//其他用戶if(S_IROTH & sb.st_mode) fileMode[7] = 'r';if(S_IWOTH & sb.st_mode) fileMode[8] = 'w'; if(S_IXOTH & sb.st_mode) fileMode[9] = 'x';//獲得用戶名和組名char *User = getpwuid(sb.st_uid)->pw_name; char *Group = getgrgid(sb.st_gid)->gr_name; //獲得時間 struct tm *fileTm = localtime(&sb.st_ctim.tv_sec);printf("%s %ld %s %s %ld %d月 %d %d:%d %s\n", fileMode, sb.st_nlink, User, Group, sb.st_size, fileTm->tm_mon+1, fileTm->tm_mday, fileTm->tm_hour, fileTm->tm_min,argv[1]);return 0; }總結
以上是生活随笔為你收集整理的Linux学习:文件属性函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux学习:文件 I/O 函数
- 下一篇: Linux学习:目录操作函数