1. 程式人生 > >與檔案和目錄操作相關的函式

與檔案和目錄操作相關的函式

獲取檔案資訊:

#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, int
flag);

以上四個函式都是用於獲取檔案相關資訊,但卻有細微差別:
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);