linux系統呼叫函式 lstat--獲取檔案屬性
所需標頭檔案:
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
函式功能:用來獲取linux作業系統下檔案的屬性。
函式原型: int stat(const char *pathname,struct stat *buf);
引數:第一個引數為傳入引數,pathname
為檔案的絕對路徑或相對路徑。第二引數為傳出引數,一個struct stat
型別的結構體指標。傳出引數可以採用下邊兩種方法,定義結構體變數struct stat st,或定義結構體指標變數strut stat *st = &st
注意,在linux作業系統下,一切皆檔案。檔案共有七種型別,分別是普通檔案、目錄檔案、管道檔案、可執行檔案、壓縮檔案、裝置檔案(字元、管道和塊)和其他檔案。
下面介紹一下struct stat
結構體:
struct stat {
dev_t st_dev; 檔案的裝置編號
ino_t st_ino; 節點
mode_t st_mode; 檔案的型別和許可權
nlink_t st_nlink; 連到該檔案的硬連結數目,剛建立的檔案值為1
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; 最後一次改變時間(指屬性)
};
下面舉例使用stat函式獲取檔案的屬性:
在linux的shell直譯器中,輸入這樣的命令stat + 檔名即可獲取檔案的屬性。如:
那麼如何在函式中獲取檔案屬性並將其打印出來呢?下面應用stat函式獲取main.c檔案的屬性。
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
int main()
{
struct stat st;//定義結構體變數,儲存所獲取的檔案屬性
int res = stat("/home/lsc/Desktop/linux/k0512/test/main.c",&st);
if(res == -1)//獲取檔案屬性失敗,errno設定為合適的值
{
perror("stat fail");
exit(1);
}
printf("大小:%d ",st.st_size);
printf("裝置:%d ",st.st_dev);
printf("塊:%d ",st_st_blocks);
printf("Inode:%d ",st.st_ino);
printf("硬連結:%d ",st.st_nlink);
printf("uid:%d ",st.st_uid);
printf("gid:% ",st.st_gid);
return 0;
}
執行結果:
和我們用stat + 檔名
命令獲取到檔案的屬性資訊是一致的。
大家可能注意到,在程式碼中併為涉及輸出st_mode屬性相關的資訊。
重點:下面著重深入的研究一下st_mode這屬性,可以通過它來獲取檔案的檔案型別以及許可權。
mode_t st_mode
是一個16位的short型別,對應16個標誌位,其組成如下:
而其,通常情況下特殊許可權位不使用。
那麼如何取出對應的位置的位獲取相關的資訊呢,Linux系統呼叫給我們提供了一系列的巨集,可以檢視man文件 man 2 stat
。
S_IFMT 0170000 //掩碼,過濾st_mode中除檔案型別以外的資訊
S_IFSOCK 0140000 //套接字
S_IFLNK 0120000 //符號連結(軟連結)
S_IFREG 0100000 //普通檔案
S_IFBLK 0060000 //塊裝置
S_IFDIR 0040000 //目錄檔案
S_IFCHR 0020000 //字元裝置
S_IFIFO 0010000 //管道
S_ISUID 0004000 //設定使用者ID
S_ISGID 0002000 //設定組ID
S_ISVTX 0001000 //粘住位
S_IRWXU 00700 //掩碼,過濾st_mode除檔案所有者許可權以外的資訊
S_IRUSR 00400 //使用者讀許可權
S_IWUSR 00200 //使用者寫許可權
S_IXUSR 00100 //使用者執行許可權
S_IRWXG 00070 //掩碼,過濾st_mode除所屬組許可權以外的資訊
S_IRGRP 00040 //讀許可權
S_IWGRP 00020 //寫許可權
S_IXGRP 00010 //執行許可權
S_IRWXO 00007 //掩碼,過濾st_mode除其他人許可權以外的資訊
S_IROTH 00004 //讀許可權
S_IWOTH 00002 //寫許可權
S_IXOTH 00001 //執行許可權
下面舉一個簡單例子,驗證一個檔案是否為普通檔案。
在當前目錄下有一個普通檔案:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#incude<sys/stat.h>
#include<sys/types.h>
int main()
{
struct stat st;
int res = stat("./test.c",&st);
if(-1 == res)
{
perror("stat fail");
exit(1);
}
if((st.st_mode & S_IFMT) == S_IFREG)
{
printf("regular file\n");
}
return 0;
}
相信完全理解了系統呼叫函式stat之後,實現一個ls -l
的命令也會變得簡單,大家可以試試。