跟這3個函式相關的,有1個很重要的struct stat結構,如下:
#include <bits/stat.h>
struct stat {
dev_t st_dev;
// ID of device containing file (unsigned long int)
ino_t st_ino; // inode 數量 (unsigned long int)
mode_t st_mode; // 保護 (unsigned int)
nlink_t st_nlink; // hard links 數量 (unsigned int)
uid_t st_uid; // user ID 擁有者 (unsigned int)
gid_t st_gid; // group ID 擁有者 (unsigned int)
dev_t st_rdev; // device ID (unsigned long int)
off_t st_size; // 以byte為單位,計算大小 (long int)
blksize_t st_blksize; // 系統I/O 區塊大小 (long int)
blkcnt_t st_blocks; // 區塊取得數量 (long int)
time_t st_atime; // 最後一次存取時間
time_t st_mtime; // 最後一次修改時間
time_t st_ctime; // 狀態修改時間
};
#include <sys/stat.h>
int fstat(int filedes, struct stat *buf);
int stat(const char *path, struct stat *buf);
int lstat(const char *path, struct stat *buf);
這乙些資料型態的大小都不是絕對的,有些還有32-bit/64-bit的差異,可以參考/usr/include/bits/types.h和/usr/include/bits/typesizes.h的定義。這3個函式執行成功會回傳0;執行失敗則是回傳-1。範例程式如下:
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <stdlib.h>
#include <strings.h>
#define FILENAME "./TEXT.TXT"
#define STAT_FLAG 0 // 0: fstat; 1: stat; 2: lstat
int main(int argc, char **argv, char *envp[])
{
struct stat stStatBuf;
int fd = -1, nRet = -1;
bzero((void *)&stStatBuf, sizeof(struct stat));
#if (STAT_FLAG == 0)
fd = open(FILENAME, O_RDONLY);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
nRet = fstat(fd, &stStatBuf);
if (nRet == -1) {
perror("fstat");
exit(EXIT_FAILURE);
}
#elif (STAT_FLAG == 1)
nRet = stat(FILENAME, &stStatBuf);
if (nRet == -1) {
perror("stat");
exit(EXIT_FAILURE);
}
#elif (STAT_FLAG == 2)
nRet = lstat(FILENAME, &stStatBuf);
if (nRet == -1) {
perror("lstat");
exit(EXIT_FAILURE);
}
#endif
printf("st_dev = %u \n", stStatBuf.st_dev);
printf("st_ino = %u \n", stStatBuf.st_ino);
printf("st_mode = %u \n", stStatBuf.st_mode);
printf("st_nlink = %u \n", stStatBuf.st_nlink);
printf("st_uid = %u \n", stStatBuf.st_uid);
printf("st_gid = %u \n", stStatBuf.st_gid);
printf("st_rdev = %d \n", stStatBuf.st_rdev);
printf("st_size = %ld \n", stStatBuf.st_size);
printf("st_blksize = %ld \n", stStatBuf.st_blksize);
printf("st_blocks = %ld \n", stStatBuf.st_blocks);
printf("st_atime= %s", ctime(&stStatBuf.st_atime));
printf("st_mtime = %s", ctime(&stStatBuf.st_mtime));
printf("st_ctime = %s", ctime(&stStatBuf.st_ctime));
#if (STAT_FLAG == 0)
close(fd);
#endif
return 0;
}
這3個函式的差異:1. fstat()函式的第1個參數所傳進去的是一個檔案描述子 (File Descriptor),所以必須先用open()函式來開啟檔案產生描述子。而不能用fopen()來產生檔案指標 (FILE *)。所以在程式運作上若是沒有read(), write()或是seek()等行為,大可不需要使用fstat()函式。
2. stat()和lstat()的運作完全一樣,差別在於若是檔案來源是一個軟連結 (Symbolic Link)的話,lstat()函式只會帶出該軟連結的檔案資訊,並不會指到原始檔案;而stat()函式則是會直接帶出原始檔案的資訊。
參考文章:Linux的fstat()函式
沒有留言:
張貼留言