與檔案和目錄操作相關的函式
獲取檔案資訊:
#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> // 成功返回0,出錯返回-1 int stat(const char *path, struct stat *buf); int fstat(int fd, struct stat *buf); int lstat(const char *path, struct stat *buf); int fstatat(int fd, const chatr *path, struct stat *buf, intflag);
以上四個函式都是用於獲取檔案相關資訊,但卻有細微差別:
stat(): 通過buf返回path指定的檔案資訊
fstat():通過buf返回在檔案描述符fd上開啟的檔案的相關資訊
lstat():與stat()大致相同,但如果path指定的檔案是符號連結時,所返回的資訊是該符號鏈
接的資訊,而stat()返回的是該符號連結引用的檔案的資訊(即跟隨該符號連結)
fstatat():與stat的區別類似於openat()與open()的區別,若path為絕對路徑時fd被忽略,若
path為相對路徑時,fstatat()會根據當前開啟目錄(fd)計算實際絕對路徑
根據flag的取值,決定fstatat()是否跟隨符號連結,預設跟隨(stat())
flag = AT_SYMLINK_NOFOLLOW(不跟隨,類似於lstat())
stat結構:
struct stat { dev_t st_dev; /* ID of device containing file */ ino_t st_ino; /* inode number */ mode_t st_mode; /* protection */ nlink_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of owner */ gid_t st_gid; /* group ID of owner*/ dev_t st_rdev; /* device ID (if special file) */ off_t st_size; /* total size, in bytes */ blksize_t st_blksize; /* blocksize for filesystem I/O */ blkcnt_t st_blocks; /* number of blocks allocated */ time_t st_atime; /* time of last access */ time_t st_mtime; /* time of last modification */ time_t st_ctime; /* time of last status change */ };
檔案許可權測試:
#include <unistd.h> // 成功返回0,出錯返回-1 // 對指定檔案path測試是否後mode指定的許可權(按實際使用者ID和實際組ID進行訪問許可權測試) int access(const char *path, int mode); int faccessat(int fd, const char *path, int mode, int flag);
faccessat()與access()的差別類似於上述的fstatat()與stat(),而有關於path表示的
是是相對路徑還是絕對路徑時的差別,這裡不再多說
mode取值:
F_OK 測試檔案是否存在
或者 R_OK、W_OK、X_OK的按位或(讀、寫、執行)
flag = AT_EACCESS時,訪問檢查用的是呼叫程序的有效使用者ID和有效組ID
設定檔案模式建立遮蔽字:
#include <sys/stat.h> // 返回之前檔案模式建立遮蔽字 mode_t umask(mode_t cmask);
cmask由之前open()使用的mode引數的九個取值的按位或構成:
S_IRUSR 使用者讀
S_IWUSR 使用者寫
S_IXUSR 使用者執行
S_IRGRP 組讀
S_IWGRP 組寫
S_IXGRP 組執行
S_IROTH 其他使用者讀
S_IWOTH 其他使用者寫
S_IXOTH 其他使用者執行
更改檔案訪問許可權:
#include <sys/stat.h> // 成功返回0,出錯返回-1 // 更改指定檔案(路徑名或檔案描述符)的訪問許可權(mode) int chmod(const char *path, mode_t mode); int fchmod(int fd, mode_t mode); int chmodat(int fd, const char *path, mode_t mode, int flag);
以上三個函式的區別在於:
指定檔案的方式(路徑名或檔案描述符,絕對路徑、相對路徑)
flag = AT_SYMLINK_NOFOLLOW,是否跟隨符號連結
這些區別與前面所述類似,此處不加以說明
mode取值:
S_ISUID 執行時設定使用者ID
S_ISGID 執行時設定組ID
S_ISVTX 儲存正文(粘著位)
以下mode值分別表示對(使用者、組、其他)設定(讀寫執行、讀、寫、執行)
S_IRWXU
S_IRUSR
S_IWUSR
S_IXUSR
S_IRWXG
S_IRGRP
S_IWGRP
S_IXGRP
S_IRWXO
S_IROTH
S_IWOTH
S_IXOTH
更改檔案的使用者ID和組ID:
#include <sys/types.h> #include <unistd.h> // 成功返回0,出錯返回-1 // 改變指定檔案的使用者ID和組ID int chown(const char *path, uid_t owner, gid_t group); int fchown(int fildes, uid_t owner, gid_t group); int fchownat(int fildes, const char *path, uid_t owner, gid_t group); int lchown(const char *pathn, uid_t owner, gid_t group);
檔案截斷:
#include <unistd.h> // 成功返回0,出錯返回-1 // 將指定檔案長度截斷為length,結果是檔案可能變長,也可以變短 // 當變短後,原始檔長度大於大於length的部分不能再訪問 // 當變長後,相當於在檔案中建立了一個空穴 int truncate(const char *path, off_t length); int ftruncate(int fd, off_t length);
建立或刪除檔案連結(硬連結,指向索引節點號(Inode Index)):
#include <unistd.h> // 建立連結 // 成功返回0,出錯返回-1 // 建立一個新的目錄項(newpath)指向一個指定檔案(existingpath) int link(const char *existingpath, const char *newpath); int linkat(int efd, const char *existingpath, int nfd, const char *newpath, int flag); // 上面兩個函式的區別在於是否使用相對路徑 // efd、nfd:若為 AT_FDCWD,表示使用當前工作目錄計算絕對路徑 // flag決定建立指向符號連結檔案指向的原始檔的連結,還是指向符號連結檔案的連結 // 刪除連結 // 成功返回0,出錯返回-1 int unlink(const char *path); int unlinkat(int fd, const char *path, int flag); // 預設unlinkat()與link()只有指定檔案時的差別 // 但,當flag = AT_REMOVEDIR時,unlinkat()可以類似於rmdir一樣刪除目錄
建立和讀取符號連結:
#include <unistd.h> // 建立一個新的目錄項sympath指向actualpath // 成功返回0,出錯返回-1 int symlink(const char *actualpath, const char *sympath); int symlinkat(const char *actualpath, int fd, const char *sympath); // 讀取符號連結 // 成功返回讀取的位元組數,出錯返回-1 ssize_t readlink(const char *path, char *buf, size_t bufsize); ssize_t readlinkat(int fd, const char *path, char *buf, size_t bufsize);
有關硬連結與符號連結的區別:http://www.cnblogs.com/sonic4x/archive/2011/08/05/2128543.html
檔案重新命名:
#include <stdio.h> // 成功返回0,出錯返回-1 int rename(const char *oldname, const char *newname); int renameat(int oldfd, const char *oldname, int newfd, const char *newname); // oldfd、newfd也可以為AT_FDCWD表示當前工作目錄
更改檔案訪問和修改時間:
#include <sys/stat.h> // 成功返回0,出錯返回-1 int utimes(const char *path, const struct timespec times[2]); int futimens(int fd, const struct timespec times[2]); int futimensat(int fd, const char *path, const struct timespec times[2], int flag); // time[0]為訪問時間、time[1]為修改時間
times[2]引數:
為空指標、或者任一陣列元素的tv_nsec欄位為UTIME_NOW時,相應時間戳設為當前時間
任一陣列元素的tv_nsec欄位為UTIME_OMIT時,相應時間戳保持不變
檔案時間(時間戳):
訪問時間、修改時間、改變時間
其中修改時間是指檔案內容最後一次被修改的時間,而改變時間是指inode最後一次被修改的時間
而上述的很多函式都會對檔案的改變時間產生影響
目錄的創建於刪除:
#include <sys/stat.h> // 成功返回0,出錯返回-1 // 建立目錄,mode指定許可權 int mkdir(const char *path, mode_t mode); int mkdirat(int fd, const char *path, mode_t mode); // 刪除目錄 int rmdir(const char *path);
目錄操作:
#include <dirent.h> // 成功返回指向DIR結構的指標(DIR結構儲存當前正在讀的目錄的有關資訊),出錯返回NULL DIR *opendir(const char *path); DIR *fdopendir(int fd); // 成功返回目錄中的第一個目錄項,出錯返回NULL struct dirent *readdir(DIR *dp); // 成功返回0,出錯返回-1 void rewinddir(DIR *dp); int closedir(DIR *dp); // 返回與dp關聯的目錄中的當前位置 long telldir(DIR *dp); void seekdir(DIR *dp, long loc);
獲取和更改當前工作目錄:
#include <unistd.h> // 成功返回buf,出錯返回NULL(buf存放CWD) cahr *getcwp(char *buf, size_t size); // 成功返回0,出錯返回-1 int chdir(const char *path); int fchdir(int fd);