利用系統呼叫stat()、lstat()以及fstat(),可獲取與檔案有關的資訊,其中大部分提取自檔案i節點。以上3個系統呼叫之間僅有的區別在於對檔案的描述方式不同。
1 stat()返回所命名檔案的相關資訊。
2 lstat()與stat()類似,區別在於如果檔案屬於符號鏈結,那麼所返回的資訊針對的是符號鏈結自身(而非符號鏈結所指向的檔案)。
3 fstat()則返回由某個開啟檔案描述符所指代檔案的相關資訊。
系統呼叫stat()和lstat()不需要對所操作的檔案本身擁有任何許可權,但針對指定pathname的父目錄要有執行(搜尋)許可權。而只要為它提供有效的檔案描述符,fstat()系統呼叫總是成功的。
上述所有系統呼叫都會在緩衝區中返回乙個由statbuf指向的stat結構,其格式如下:
裝置id和i節點號
st_dev欄位標識檔案所駐留的裝置。st_ino欄位包含了檔案的i節點號。利用這兩個字段,可以在所有檔案系統中唯一表示某個檔案。
如果是針對裝置的i節點,那麼st_rdev欄位則包含裝置的主、輔id。利用巨集major()和minor(),可以提取主、輔id。在linux系統上,要使用這兩個巨集,需要定義_bsd_source巨集,然後include定義這兩個巨集的標頭檔案。
由於major()和minor()所返回的整型值大小隨uinx實現的不同而各有不用。為保證可移植性,列印時總是將返回值強制轉換為long。
檔案所有權
st_uid和st_gid欄位分別表示檔案的屬主(使用者id)和屬組(組id)。
鏈結數
st_nlink欄位包含了指向檔案的(硬)鏈結數。
檔案型別及許可權
st_mode欄位內含有位掩碼,起表示檔案型別和指定檔案許可權的雙重作用。下圖為該字段所含各位的布局情況。
檔案型別 許可權
ugtrwxr
wxrw
xlinux使用了st_mode欄位中的4位來標識檔案型別位。st_mode欄位與常量s_ifmt相與(&),可從該字段中提取出檔案型別。將計算結果與一系列常量進行比較,即可確定檔案型別:
if((statbuf.st_mode & s_ifmt) == s_ifreg)
printf(「regularfile\n」);
在linux中可利用標準巨集將其簡化:
if(s_isreg(statbuf.st_mode))
printf(「regularfile\n」);
常 量
測 試 巨集
文 件 類 型
s_ifreg
s_isreg()
常規檔案
s_ifdir
s_isdir()
目錄s_ifchr
s_ischr()
字元裝置
s_ifblk
s_isblk()
塊裝置s_ififo
s_isfifo()
fifo或管道
s_ifsock
s_issock()
套接字s_iflnk
s_islnk()
符號鏈結
針對stat結構中的st_mode來檢查檔案型別的巨集
想從中獲取s_ifsock和s_issock()的定義,必須定義_bsd_source特性測試巨集,或將_xopen_source定義為不小於500的值。
st_mode欄位的低12位定義了檔案許可權。最低9位分別用來表示檔案屬主、屬組以及其他使用者的讀、寫、執行許可權。
檔案大小、已分配塊以及最優i/o塊大小
對於常規檔案,st_size欄位表示檔案的位元組數。對於符號鏈結,st_size欄位則表示鏈結所指路徑名的長度,以位元組為單位。對於共享記憶體物件,該字段則表示物件的大小。
st_blocks欄位表示分配給檔案的總塊數,塊大小為512位元組,其中包括了為指標塊所分配的空間。st_blocks欄位記錄了實際分配給檔案的磁碟塊數量。如果檔案內含空洞,該值將小於從相應檔案位元組數字段(st_size)的值。
st_blksize欄位所指並非底層檔案系統的塊大小,而是針對檔案系統上檔案進行i/o操作時的最優塊大小(以位元組為單位)。一般而言,st_blksize的返回值為4096。
檔案時間戳
st_time、st_mtime和st_ctime欄位,分別記錄了對檔案的上次訪問時間、上次修改時間以及檔案狀態傳送改變的上次時間。這3個字段的型別都是time_t,記錄了自新紀元(epoch)以來的秒數。
示例程式
(獲取並解釋檔案的stat資訊)
#define _bsd_source
#include #include #include #include #include #include #include #define fp_special 1
#define str_size sizeof("rwxrwxrwx")
typedef enum boolean;
static char *filepermstr(mode_t perm, int flags)
static void showstatinfo(struct stat *st)
printf("device containing i-node: major=%ld minor=%ld\n",
(long) major(st->st_dev), (long) minor(st->st_dev));
printf("i-node number: %ld\n", (long) st->st_ino);
printf("mode: %lo (%s)\n", (unsigned long) st->st_mode,
filepermstr(st->st_mode, 0));
if (st->st_mode & (s_isuid| s_isgid| s_isvtx))
printf(" special bits set: %s%s%s\n",
(st->st_mode & s_isuid) ? "set-uid " : "",
(st->st_mode & s_isgid) ? "set-gid " : "",
(st->st_mode & s_isvtx) ? "sticky " : "");
printf("number of (hard) links: %ld\n", (long) st->st_nlink);
printf("ownership: uid=%ld gid=%ld\n",
(long) st->st_uid, (long) st->st_gid);
if (s_ischr(st->st_mode) || s_isblk(st->st_mode))
printf("device number (st_rdev): major=%ld; minor=%ld\n",
(long) major(st->st_rdev), (long) minor(st->st_rdev));
printf("file size: %lld bytes\n", (long long) st->st_size);
printf("optimal i/o block size: %ld bytes\n", (long) st->st_blksize);
printf("512b blocks allocated: %lld\n", (long long) st->st_blocks);
printf("last file access: %s\n", ctime(&st->st_atime));
printf("last file modification: %s\n", ctime(&st->st_mtime));
printf("last status change: %s\n", ctime(&st->st_ctime));
}int main(int argc, char *argv)
} else
showstatinfo(&st);
exit(1);
}
以下是執行結果:
Linux系統程式設計之檔案程式設計
目錄 一 檔案程式設計 1 linux檔案 2 檔案描述符 file descriptor 3 常用api open write read lseek close 1 open 開啟檔案函式 2 close 關閉檔案 3 write 寫檔案 4 read 讀檔案 5 lseek 游標定位 linux...
系統程式設計之檔案系統程式設計
系統呼叫 所有的作業系統都提供多種服務的入口點,程式由此向核心請求服務。這些可直接進入核心的入口點被稱為系統呼叫。不同作業系統提供了自己的一套系統呼叫,所以系統呼叫無法實現跨平台使用。而且頻繁地系統呼叫,在使用者態和核心態之間切換,很耗費資源,效率不高。c標準庫提供了操作檔案的標準i o函式庫,與系...
linux系統程式設計之檔案I O
一 檔案描述符 linux系統中,所有開啟的檔案都對應乙個數字,這個數字由系統來分配,稱為檔案描述符。pcb程序控制塊裡有檔案描述符表,以陣列形式存放於核心區。乙個程序預設開啟3個檔案描述符 stdin fileno 0 stdout fileno 1 stderr fileno 2 新開啟檔案返回...