stat函數(stat、fstat、lstat)

#include <sys/types.h>

#include <sys/stat.h>

#include <unistd.h>???? //需包含頭文件

有如下三個函數的函數原型:

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

第一個形參:指出文件(文件路徑); 第二個形參:出參數(函數對該參數操作,然后傳出)。

int fstat(int fd, struct stat *buf);

fstat函數與stat函數的功能一樣,只是第一個形參是文件描述符。

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

lstat函數的形參跟stat函數的形參一樣。其功能也跟stat函數功能一樣,僅有一點不同:stat函數是穿透(追蹤)函數,即對軟鏈接文件進行操作時,操作的是鏈接到的那一個文件,不是軟鏈接文件本身;而lstat函數是不穿透(不追蹤)函數,對軟鏈接文件進行操作時,操作的是軟鏈接文件本身。

以上三個函數:成功返回0,失敗返回-1,并且將詳細錯誤信息賦值給errno全局變量。

其它Linux系統函數類似,帶l表示不追蹤,不帶l表示追蹤(穿透)。如:ls –l命令查看的文件屬性,是不追蹤(不穿透)的;rm刪除文件時,是不追蹤的;Vi和Vim是穿透的;對于穿透的命令,是無法判斷文件是不是軟鏈接文件,比如ls –l命令,其是不穿透的,因此可以判斷是否是軟鏈接文件;如果是用stat函數實現的ls –l命令,則是穿透的,對于查看原文件和鏈接文件的屬性是一樣的,無法區別兩者,因此可以考慮用lstat函數來實現ls –l命令的功能。

注意:創建軟鏈接最好用絕對路徑? ln –s 原文件 軟鏈接文件(采用絕對路徑)

statlstatfstat函數中 struct stat類型的說明:

struct stat {

?????????????? dev_t???? st_dev;???? /* 文件的設備編號 */

????????????? ?ino_t???? st_ino;???? /* 索引結點編號 */

?????????????? mode_t??? st_mode;??? /* 文件類型和權限*/

?????????????? nlink_t?? st_nlink;?? /*硬鏈接數 */

?????????????? uid_t???? st_uid;???? /*用戶ID*/

?????????????? gid_t???? st_gid;???? /* ID*/

????? ?????????dev_t???? st_rdev;??? /* 設備類型(若此文件為設備文件,則為設備編號*/

???????????? ??off_t??? ??st_size;??? /* 文件大小*/

?????????????? blksize_t ??st_blksize; /*文件系統的I/O緩沖區大小*/

???????????? ??blkcnt_t ??st_blocks;? /* 塊數 */

?????????????? time_t??? st_atime;?? /* 訪問時間 */

?????????????? time_t??? st_mtime;?? /* 修改時間 */

?????????????? time_t??? st_ctime;?? /* 更改時間 */

???????? };? //標紅為重點內容

struct stat結構體位于inode(索引結點)中,但是其內部不包含文件名。文件名位于位于文件的目錄項dentry中(即簡化的FCB),其包含文件名和inode編號。通過denty的inode編號可以找到inode,進一步找到文件本身。硬鏈接就是denty(目錄項)。

上述結構體中,對st_mode成員做一個詳細的介紹:

mode_t??? st_mode;??? /* 文件類型和權限*/

st_mode變量(mode_t類型):該變量占 2byte共16位,為16位的整型值。用于儲存文件類型和權限。 如下圖所示:

每一位均為二進制數。r代表4,即100;w代表2,即010;x代表1,即001。由于總共16位二進制數,因此需要6位8進制數來進行表示,其中8進制數以0開頭,共7位。

其他人權限(0~2位)。讀權限:0000004,在所給函數頭文件中進行了宏定義為:S_IROTH;寫:0000002,S_IWOTH;執行:0000001,S_IXOTH。 掩碼為:0000007,S_IRWXO ?掩碼的作用:st_mode & 掩碼 就可以過濾st_mode中除其他人權限以外的信息,所得結果直接是其他人的權限信息,下面原理相同。

所屬組權限(3~5位)。讀權限:0000040, S_IRGRP;寫:0000020,S_IWGRP;執行:0000010,S_IXGRP。 掩碼為:0000070,S_IRWXG。

所屬主權限(6~8位)。讀權限:0000400, S_IRUSR;寫:0000200,S_IWUSR;執行:0000100,S_IXUSR。 掩碼為:0000700,S_IRWXU。

特殊權限位(9~11位)。SUID:0004000, S_ISUID;SGID:0002000,S_ISGID;SBIT:0001000,S_ISVTX。 //特殊權限位很少用

文件類型(12~15位,共7種類型文件)。套接字(socket)文件s:0140000,S_IFSOCK;鏈接文件(軟鏈接)l:0120000,S_IFLNK;普通文件-:0100000,S_IFREG;塊設備文件b:0060000,S_IFBLK;目錄文件d:0040000,S_IFDIR;字符設備文件c:0020000,S_IFCHR;管道文件p:0010000,S_IFIFO。? ??掩碼:0170000? 作用一樣,st_mode & 掩碼 的結果與七種類型的宏相比較,就可以判斷是哪一種文件。

強調一下特殊權限位SBIT(粘滯位)的功能:1.對目錄設置粘滯位,則該目錄內的文件只能被文件所有者、超級用戶和目錄所有者這三類用戶刪除,其他用戶都沒有刪除的權限;2.對文件設置了粘滯位,那么在內存資源十分緊張的情況下,也不會把該文件放回到磁盤上。如磁盤的對換區SWAP,當內存緊張,優先級別低的進程會被暫時放回到對換區中,但是一旦設置了粘滯位,則不會放回磁盤,依然處于內存。

下面是說明stat函數的使用的代碼:

//運用stat函數實現查看文件大小屬性的功能

[root@localhost work]# vim statuse.c

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>int main( int argc,char *argv[ ] )   //命令行參數
{if( argc < 2 )printf("./statuse filename1 filename2 ...\n");struct stat zsx;int ret;int i=1;for( i=1;i<argc;i++ ){ret = stat( argv[i],&zsx);   //stat函數獲取文件的屬性,穿透的if( ret == -1 ){perror("stat filename");exit(1);}int size = (int)zsx.st_size;   //注意,必須強制轉換,后者變量是off_t類型printf("%s      %d\n",argv[i],size);}return 0;
}

[root@localhost work]# gcc -pipe -ggdb3 -pedantic -Wall statuse.c -o statuse

[root@localhost work]# ls

english.txt? ls-l.c? stat.c? statuse? statuse.c

[root@localhost work]# ./statuse english.txt ls-l.c stat.c statuse statuse.c

english.txt????? 109055

ls-l.c?????? 2204

stat.c?????? 416

statuse???? 57468

statuse.c? 535

?[root@localhost work]# ll english.txt

-rwxrwxrwx. 1 root root 109055 Mar 19 10:30 english.txt

//運用stat函數實現ls –l 命令的功能

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>int main(int argc, char* argv[])
{if(argc < 2)int main(int argc, char* argv[])
{if(argc < 2){printf("./a.out filename\n");exit(1);}struct stat st;int ret = stat(argv[1], &st);if(ret == -1){perror("stat");exit(1);}// 存儲文件類型和訪問權限char perms[11] = {0};// 判斷文件類型switch(st.st_mode & S_IFMT){case S_IFLNK:perms[0] = 'l';break;case S_IFDIR:perms[0] = 'd';break;case S_IFREG:perms[0] = '-';break;case S_IFBLK:perms[0] = 'b';break;case S_IFCHR:perms[0] = 'c';break;case S_IFSOCK:perms[0] = 's';break;case S_IFIFO:perms[0] = 'p';break;default:perms[0] = '?';break;}// 判斷文件的訪問權限// 文件所有者perms[1] = (st.st_mode & S_IRUSR) ? 'r' : '-';perms[2] = (st.st_mode & S_IWUSR) ? 'w' : '-';perms[3] = (st.st_mode & S_IXUSR) ? 'x' : '-';// 文件所屬組perms[4] = (st.st_mode & S_IRGRP) ? 'r' : '-';perms[5] = (st.st_mode & S_IWGRP) ? 'w' : '-';perms[6] = (st.st_mode & S_IXGRP) ? 'x' : '-';// 其他人perms[7] = (st.st_mode & S_IROTH) ? 'r' : '-';perms[8] = (st.st_mode & S_IWOTH) ? 'w' : '-';perms[9] = (st.st_mode & S_IXOTH) ? 'x' : '-';// 硬鏈接計數int linkNum = st.st_nlink;// 文件所有者char* fileUser = getpwuid(st.st_uid)->pw_name;// 文件所屬組char* fileGrp = getgrgid(st.st_gid)->gr_name;// 文件大小int fileSize = (int)st.st_size;// 修改時間char* time = ctime(&st.st_mtime);char mtime[512] = {0};strncpy(mtime, time, strlen(time)-1);char buf[1024];sprintf(buf, "%s  %d  %s  %s  %d  %s  %s", perms, linkNum, fileUser, fileGrp, fileSize, mtime, argv[1]);printf("%s\n", buf);return 0;
}

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/385399.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/385399.shtml
英文地址,請注明出處:http://en.pswp.cn/news/385399.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

1062. Talent and Virtue (25)

About 900 years ago, a Chinese philosopher Sima Guang wrote a history book in which he talked about peoples talent and virtue. According to his theory, a man being outstanding in both talent and virtue must be a "sage&#xff08;圣人&#xff09;"…

access、strtol函數的使用(后者為C庫函數)

#include <unistd.h> int access(const char *pathname, int mode); 作用&#xff1a;檢查調用該函數的進程是否可以對指定的文件執行某種操作。 第一個形參&#xff1a;文件名&#xff1b;第二個形參&#xff1a;R_OK&#xff08;是否可讀&#xff09;、W_OK&#xf…

chmod、chown函數的使用

#include <sys/stat.h> int chmod(const char *path, mode_t mode); int fchmod(int fd, mode_t mode); 作用&#xff1a;改變指定文件的權限。第二個參數&#xff1a;mode必須為一個8進制數&#xff1b;返回值為0表示成功&#xff0c;-1表示失敗。 //代碼 #include…

606. 根據二叉樹創建字符串

你需要采用前序遍歷的方式&#xff0c;將一個二叉樹轉換成一個由括號和整數組成的字符串。 空節點則用一對空括號 "()" 表示。而且你需要省略所有不影響字符串與原始二叉樹之間的一對一映射關系的空括號對。 示例 1: 輸入: 二叉樹: [1,2,3,4] 1 / \ …

truncate、rename函數的使用

#include <unistd.h> #include <sys/types.h> int truncate(const char *path, off_t length); int ftruncate(int fd, off_t length); 作用&#xff1a;用于拓展或截斷文件。將參數path 指定的文件大小改為參數length 指定的大小。如果原來的文件大小比參數le…

【Leetcode】112. 路徑總和

給定一個二叉樹和一個目標和&#xff0c;判斷該樹中是否存在根節點到葉子節點的路徑&#xff0c;這條路徑上所有節點值相加等于目標和。 說明: 葉子節點是指沒有子節點的節點。 示例: 給定如下二叉樹&#xff0c;以及目標和 sum 22&#xff0c; 5 / \ …

link、symlink、readlink、unlink函數的使用

#include <unistd.h> int link(const char *oldpath, const char *newpath); 作用&#xff1a;創建一個硬鏈接 0成功 -1 失敗 //代碼 #include <stdio.h> #include <stdlib.h> #include <unistd.h>int main(int argc, char* argv[]) {if(ar…

【Leetcode】113. 路徑總和 II

給定一個二叉樹和一個目標和&#xff0c;找到所有從根節點到葉子節點路徑總和等于給定目標和的路徑。 說明: 葉子節點是指沒有子節點的節點。 示例: 給定如下二叉樹&#xff0c;以及目標和 sum 22&#xff0c; 5 / \ 4 8 / / \ …

目錄操作相關的系統函數

主要介紹幾個常用函數的使用方法&#xff1a;chdir&#xff08;改變進程的當前工作目錄&#xff09;、getcwd&#xff08;獲取當前進程的工作目錄&#xff09;、mkdir&#xff08;創建目錄&#xff09;、rmdir&#xff08;刪除空目錄&#xff09;、opendir&#xff08;打開一個…

1079. Total Sales of Supply Chain (25)

A supply chain is a network of retailers&#xff08;零售商&#xff09;, distributors&#xff08;經銷商&#xff09;, and suppliers&#xff08;供應商&#xff09;-- everyone involved in moving a product from supplier to customer. Starting from one root suppli…

chdir、getcwd、mkdir、rmdir函數

#include <unistd.h> int chdir(const char *path); int fchdir(int fd); 作用&#xff1a;改變調用這一函數的進程&#xff08;即程序執行&#xff09;的當前工作目錄&#xff0c;注意不是shell的當前工作目錄。 返回值&#xff1a;0成功 -1失敗 #include <unis…

【Leetcode | 235】 235. 二叉搜索樹的最近公共祖先

給定一個二叉搜索樹, 找到該樹中兩個指定節點的最近公共祖先。 百度百科中最近公共祖先的定義為&#xff1a;“對于有根樹 T 的兩個結點 p、q&#xff0c;最近公共祖先表示為一個結點 x&#xff0c;滿足 x 是 p、q 的祖先且 x 的深度盡可能大&#xff08;一個節點也可以是它自己…

1090. Highest Price in Supply Chain (25)

A supply chain is a network of retailers&#xff08;零售商&#xff09;, distributors&#xff08;經銷商&#xff09;, and suppliers&#xff08;供應商&#xff09;-- everyone involved in moving a product from supplier to customer. Starting from one root suppli…

opendir、readdir和closedir函數

注意&#xff1a;在Linux中&#xff0c;目錄的輸入格式&#xff1a;/mnt//fghs、/mnt/fghs、/mnt/fghs和/mnt/fghs//是等效的&#xff0c;都一樣。 #include <sys/types.h> #include <dirent.h> DIR *opendir(const char *name); DIR *fdopendir(int fd); 返回…

146. LRU緩存機制

運用你所掌握的數據結構&#xff0c;設計和實現一個 LRU (最近最少使用) 緩存機制。它應該支持以下操作&#xff1a; 獲取數據 get 和 寫入數據 put 。 獲取數據 get(key) - 如果密鑰 (key) 存在于緩存中&#xff0c;則獲取密鑰的值&#xff08;總是正數&#xff09;&#xff…

dup和dup2函數

#include <unistd.h> int dup(int oldfd); int dup2(int oldfd, int newfd); 作用&#xff1a;dup函數實現對一個文件的文件描述符進行復制&#xff0c;復制之后該進程就會新增加一一個文件描述符指向該文件&#xff08;即實現同一個文件對應多個文件描述符&#xff0…

fcntl函數(網絡編程會用)

#include <unistd.h> #include <fcntl.h> int fcntl&#xff08;int fd, int cmd&#xff09;&#xff1b; int fcntl&#xff08;int fd, int cmd, long arg&#xff09;&#xff1b;//long 長整型 int fcntl&#xff08;int fd, int cmd, struct flock *lock…

189. 旋轉數組

給定一個數組&#xff0c;將數組中的元素向右移動 k 個位置&#xff0c;其中 k 是非負數。 示例 1: 輸入: [1,2,3,4,5,6,7] 和 k 3 輸出: [5,6,7,1,2,3,4] 解釋: 向右旋轉 1 步: [7,1,2,3,4,5,6] 向右旋轉 2 步: [6,7,1,2,3,4,5] 向右旋轉 3 步: [5,6,7,1,2,3,4]示例 2: 輸…

58. 最后一個單詞的長度

給定一個僅包含大小寫字母和空格 的字符串&#xff0c;返回其最后一個單詞的長度。 如果不存在最后一個單詞&#xff0c;請返回 0 。 說明&#xff1a;一個單詞是指由字母組成&#xff0c;但不包含任何空格的字符串。 示例: 輸入: "Hello World" 輸出: 5 clas…

CPU和MMU(內存管理單元)

CPU的架構&#xff1a;要求能夠理解從源程序到微指令的整個經歷過程&#xff1a;存儲器的層次結構&#xff08;網絡資源下載到硬盤、磁盤緩存、內存、Cache、寄存器&#xff09;&#xff1b;CPU的四大部分&#xff1a;ALU、CU、中斷系統和寄存器&#xff1b;程序執行的整個過程…