link: 建立文件硬連接
頭文件: unistd.h
函數(shù)定義: int link(const char *oldpath, const char *newpath);
說明: link()以參數(shù)newpath指定的名稱來建立一個新的連接(硬連接)到參數(shù)oldpath所指定的已存在文件. 如果參數(shù)newpath指定的名稱為一已存在的文件則不會建立連接. 成功則返回0, 失敗返回-1, 錯誤原因存于errno.
錯誤代碼:
EXDEV 參數(shù)oldpath與newpath不是建立在同一文件系統(tǒng)
EPERM 參數(shù)oldpath與newpath所指的文件系統(tǒng)不支持硬連接
EROFS 文件存在于只讀文件系統(tǒng)內(nèi)
EFAULT 參數(shù)oldpath或newpath指針超出可存取內(nèi)存空間
ENAMETOLLONG 參數(shù)oldpath或newpath太長
ENOMEM 核心內(nèi)存不足
EEXIST 參數(shù)newpath所指的文件名已存在
EMLINK 參數(shù)oldpath所指的文件已達最大連接數(shù)目
ELOOP 參數(shù)pathname有過多符號連接問題
ENOSPC 文件系統(tǒng)的剩余空間不足
EIO I/O存取錯誤
附加說明: link()所建立的硬連接無法跨越不同文件系統(tǒng), 如果需要請改用symlink().
lstat: 由文件描述詞取得文件狀態(tài)
頭文件: sys/stat.h unistd.h
函數(shù)定義: int lstat(const char *file_name, struct stat *buf);
說明: lstat()與stat()作用完全相同, 都是取得參數(shù)file_name所指的文件狀態(tài), 其差別在于, 當文件為符號連接時, lstat()會返回該link本身的狀態(tài). 詳細內(nèi)容請參考stat(). 執(zhí)行成功則返回0, 失敗返回-1, 錯誤代碼存于errno.
nftw: 遍歷目錄樹
頭文件: ftw.h
函數(shù)定義: int nftw(const char *dir, int (*fn)(const char *file, const struct stat *sb, int flag, struct FTW *s), depth, int flags);
說明: nftw()與ftw()很像, 都是從參數(shù)dir指定的目錄開始, 往下一層層地遞歸式遍歷子目錄. 每進入一個目錄, 便會調(diào)用參數(shù)*fn定義的函數(shù)來處理. nftw()會傳四個參數(shù)給fn(), 第一個參數(shù)*file指向當時所在的目錄路徑, 第二個參數(shù)是*sb, 為stat結(jié)構(gòu)指針(結(jié)構(gòu)定義請參考stat()), 第三個參數(shù)為旗標, 有以下幾種可能:
FTW_F 一般文件
FTW_D 目錄
FTW_DNR 不可讀取的目錄. 此目錄以下將不被遍歷
FTW_SL 符號連接
FTW_NS 無法取得stat結(jié)構(gòu)數(shù)據(jù), 有可能是權(quán)限問題
FTW_DP 目錄, 而且其子目錄都已被遍歷過了.
FTW_SLN 符號連接, 但連接不存在文件
fn()的第四個參數(shù)是FTW結(jié)構(gòu), 定義如下:
struct FTW{
int base;
int level;
}
level代表遍歷當時的深度, nftw()第三個參數(shù)depth代表nftw()在進行遍歷目錄時可同時打開的文件數(shù). ftw()在遍歷時每一層目錄至少需要一個文件描述詞, 如果遍歷時用完了depth所給予的限制數(shù)目, 整個遍歷將因不斷地關(guān)閉文件和打開文件操作而顯得緩慢. nftw()最后一個參數(shù)flags用來指定遍歷時的動作, 可以指定下列的操作或用OR組合:
FTW_CHDIR 在讀目錄之前用chdir()移到此目錄
FTW_DEPTH 執(zhí)行深度優(yōu)先搜索. 在遍歷此目錄前先將所有子目錄遍歷完
FTW_MOUNT 遍歷時不要跨越到其他文件系統(tǒng)
FTW_PHYS 不要遍歷符號連接的目錄. 預設(shè)會遍歷符號連接目錄
如果要結(jié)束ftw()的遍歷, fn()只需返回一非零值即可, 此值同時也會是ftw()的返回值, 否則ftw()會試著走完所有的目錄, 然后返回0. 遍歷中斷則返回fn()函數(shù)的返回值, 全部遍歷完則返回0. 如有錯誤發(fā)生則返回-1.
附加說明: 由于ftw()會動態(tài)配置內(nèi)存使用, 請使用正常方式(fn函數(shù)返回非0值)來中斷遍歷, 不要在fn函數(shù)中使用longjmp().
opendir: 打開目錄
頭文件: sys/types.h dirent.h
函數(shù)定義: DIR *opendir(const char *name);
說明: opendir()用來打開參數(shù)name指定的目錄, 并返回DIR*形態(tài)的目錄流, 和open()類似, 接下來對目錄的讀取和搜索都要使用此返回值. 成功則返回DIR*型態(tài)的目錄流, 打開失敗則返回NULL.
錯誤代碼:
EACCESS 權(quán)限不足
EMFILE 已達到進程可同時打開的文件數(shù)上限
ENFILE 已達到系統(tǒng)可同時打開的文件數(shù)上限
ENOTDIR 參數(shù)name非真正的目錄
ENOENT 參數(shù)name指定的目錄不存在, 或是參數(shù)name為一空字符串
ENOMEM 核心內(nèi)存不足
readdir: 讀取目錄
頭文件: sys/types.h dirent.h
定義函數(shù): struct dirent *readdir(DIR *dir);
說明: readdir()返回參數(shù)dir目錄流的下個目錄進入點. 結(jié)構(gòu)dirent定義如下:
struct dirent{
ino_t d_ino;
ff_t d_off;
signed short int d_reclen;
unsigned char d_type;
char d_name[256];
};
d_ino 此目錄進入點的inode
d_off 目錄文件開頭至此目錄進入點的位移
d_reclen _name的長度, 不包含NULL字符
d_type d_name所指的文件類型
d_name 文件名
成功則返回下個目錄進入點, 有錯誤發(fā)生或讀取到目錄文件尾則返回NULL. EBADF參數(shù)dir為無效的目錄流.
應用舉例:
/* 讀取/etc/rc.d目錄文件結(jié)構(gòu), 然后顯示目錄下的文件 */
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
int main(void)
{
DIR *dir;
struct dirent *ptr;
int i;
dir = opendir("/etc/rc.d");
while((ptr = readdir(dir)) != NULL)
{
printf("d_name: %s\n", ptr->d_name);
}
return 0;
}
運行結(jié)果:
d_name: rc1.d
d_name: rc3.d
d_name: rc
d_name: rc2.d
d_name: rc0.d
d_name: rc.sysinit
d_name: ..
d_name: rc6.d
d_name: rc4.d
d_name: init.d
d_name: rc.local
d_name: rc5.d
d_name: .
readlink: 取得符號連接所指的文件
頭文件: unistd.h
函數(shù)定義: int readlink(const char *path, char *buf, size_t bufsize);
說明: readlink()會將參數(shù)path的符號連接內(nèi)容存到參數(shù)buf所指的內(nèi)存空間, 返回的內(nèi)容不是以NULL作字符串結(jié)尾, 但會將字符串的字符數(shù)返回. 若參數(shù)bufsiz小于符號連接的內(nèi)容長度, 過長的內(nèi)容會被截斷. 執(zhí)行成功則傳符號連接所指的文件路徑字符串, 失敗則返回-1, 錯誤代碼存于errno.
錯誤代碼:
EACCESS 取文件時被拒絕, 權(quán)限不夠
EINVAL 參數(shù)bufsiz為負數(shù)
EIO I/O存取錯誤
ELOOP 欲打開的文件有過多符號連接問題
ENAMETOOLONG 參數(shù)path的路徑名稱太長
ENOENT 參數(shù)path所指定的文件不存在
ENOMEM 核心內(nèi)存不足
ENOTDIR 參數(shù)path路徑中的目錄存在但卻非真正的目錄
realpath: 將相對目錄路徑轉(zhuǎn)換成絕對路徑
頭文件: limits.h stdlib.h
函數(shù)定義: char *realpath(const char *path, char *resolved_path);
說明: realpath()用來將參數(shù)path所指的相對路徑轉(zhuǎn)換成絕對路徑存于參數(shù)resolved_path所指的字符串數(shù)組中. 如果轉(zhuǎn)換成功則返回指向resolved_path的指針. 失敗返回NULL, 錯誤代碼存于errno.
remove: 刪除文件或目錄
頭文件: stdio.h
函數(shù)定義: int remove(const char *pathname);
說明: remove()會刪除參數(shù)pathname指定的文件. 如果參數(shù)pathname為一文件, 則調(diào)用unlink()處理, 若參數(shù)pathname為一目錄, 則調(diào)用rmdir()來處理. 請參考unlink()與rmdir(). 成功則返回0, 失敗則返回-1, 錯誤原因存于errno.
錯誤代碼:
EROFS 欲寫入的文件存在于只讀文件系統(tǒng)內(nèi)
EFAULT 參數(shù)pathname指針超出可存取內(nèi)存空間
ENAMETOOLONG 參數(shù)pathname太長
ENOMEM 核心內(nèi)存不足
ELOOP 參數(shù)pathname有過多符號連接問題
EIO I/O存取錯誤.
rename: 更改文件名或位置
頭文件: stdio.h
函數(shù)定義: int rename(const char *oldpath, const char *newpath);
說明: rename()會將參數(shù)oldpath所指定的文件名稱改為參數(shù)newpath所指的文件名稱. 若newpath所指定的文件已存在, 則會被刪除. 執(zhí)行成功則返回0, 失敗返回-1, 錯誤原因存于errno.
rewinddir: 將讀取目錄的位置設(shè)為開頭位置
頭文件: sys/types.h dirent.h
函數(shù)定義: void rewinddir(DIR *dir);
說明: rewinddir()用來設(shè)置參數(shù)dir目錄流目前的讀取位置為原來開頭的讀取位置. EBADF表示dir為無效的目錄流.
scandir: 讀取特定的目錄數(shù)據(jù)
頭文件: dirent.h
函數(shù)定義: int scandir(const char *dir, struct dirent ***namelist, int (*select)(const struct dirent *), int (*compar)(const struct dirent**, const struct dirent**));
說明: scandir()會掃描參數(shù)dir指定的目錄文件, 經(jīng)由參數(shù)select指定的函數(shù)來挑選目錄結(jié)構(gòu)至參數(shù)namelist數(shù)組中, 最后在調(diào)用參數(shù)compar指定的函數(shù)來排序namelist數(shù)組中的目錄數(shù)據(jù). 每次從目錄文件中讀取一個目錄結(jié)構(gòu)后便將此結(jié)構(gòu)傳給參數(shù)select所指的函數(shù), select函數(shù)若不想要將此目錄機構(gòu)復制到namelist數(shù)組就返回0, 若select為空指針則代表選擇所有的目錄結(jié)構(gòu). scandir()會調(diào)用qsort()來排序數(shù)據(jù), 參數(shù)compar則為qsort()的參數(shù), 若是要排列目錄名稱字母則可使用alphasort(). 結(jié)構(gòu)dirent定義請參考readdir(). 成功則返回復制到namelist數(shù)組中的數(shù)據(jù)結(jié)構(gòu)數(shù)目, 有錯誤發(fā)生則返回-1. ENOMEM表示核心內(nèi)存不足.
應用舉例:
/* 讀取/目錄下文件名長度大于5的目錄結(jié)構(gòu) */
#include <stdio.h>
#include <string.h>
#include <dirent.h>
int select(const struct dirent *dir)
{
if(strlen(dir->d_name) > 5)
return 1;
else
return 0;
}
int main(void)
{
struct dirent **namelist;
int i, total;
total = scandir("/", &namelist, select, 0);
if(total < 0)
perror("scandir");
else
{
for(i = 0; i < total; i++)
{
printf("%s\n", namelist[i]->d_name);
printf("total = %d\n", total);
}
}
return 0;
}
運行結(jié)果:
selinux
total = 3
.autofsck
total = 3
lost+found
total = 3
seekdir: 設(shè)置下回讀取目錄的位置
頭文件: dirent.h
函數(shù)定義: void seekdir(DIR *dir, off_t offset);
說明: seekdir()用來設(shè)置參數(shù)dir目錄流目前的讀取位置, 在調(diào)用readdir()時便從此新位置開始讀取. 參數(shù)offset代表距離目錄文件開頭的偏移量. EBADF表示參數(shù)dir為無效路徑.
stat: 取得文件狀態(tài)
頭文件: sys/stat.h unistd.h
函數(shù)定義: int stat(const char *file_name, struct stat *buf);
說明: stat()用來將參數(shù)file_name所指的文件狀態(tài), 復制到參數(shù)buf所指的結(jié)構(gòu)中. 下面是struct stat內(nèi)各參數(shù)的說明:
struct stat
{
dev_t st_dev; /* device */
ino_t st_ino; /* inode */
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 type */
off_t st_size; /* total size, in bytes */
unsigned long st_blksize; /* blocksize for filesystem I/O */
unsigned long st_blocks; /* number of blocks allocated */
time_t st_atime; /* time of lastaccess */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last change */
};
st_dev 文件的設(shè)備編號
st_ino 文件的i-node
st_mode 文件的類型和存取的權(quán)限
st_nlink 連到該文件的硬連接數(shù)目, 剛建立的文件值為1
st_uid 文件所有者的用戶識別碼
st_gid 文件所有者的組識別碼
st_rdev 若此文件為裝置設(shè)備文件, 則為其設(shè)備編號
st_size 文件大小, 以字節(jié)計算
st_blksize 文件系統(tǒng)的I/O緩沖區(qū)大小
st_blcoks 占用文件區(qū)塊的個數(shù), 每一區(qū)塊大小為512個字節(jié)
st_atime 文件最近一次被存取或被執(zhí)行的時間, 一般只有在用mknod, utime, read, write與tructate時改變
st_mtime 文件最后一次被修改的時間, 一般只有在用mknod, utime和write時才會改變
st_ctime i-node最近一次被更改的時間, 此參數(shù)會在文件所有者, 組, 權(quán)限被更改時更新
先前所描述的st_mode則定義了下列數(shù)種情況:
S_IFMT 0170000 文件類型的位遮罩
S_IFSOCK 0140000 scoket
S_IFLNK 0120000 符號連接
S_IFREG 0100000 一般文件
S_IFBLK 0060000 區(qū)塊裝置
S_IFDIR 0040000 目錄
S_IFCHR 0020000 字符裝置
S_IFIFO 0010000 先進先出
S_ISUID 04000 文件的(set user-id on execution)位
S_ISGID 02000 文件的(set group-id on execution)位
S_ISVTX 01000 文件的sticky位
S_IRUSR(S_IREAD) 00400 文件所有者具可讀取權(quán)限
S_IWUSR(S_IWRITE) 00200 文件所有者具可寫入權(quán)限
S_IXUSR(S_IEXEC) 00100 文件所有者具可執(zhí)行權(quán)限
S_IRGRP 00040 用戶組具可讀取權(quán)限
S_IWGRP 00020 用戶組具可寫入權(quán)限
S_IXGRP 00010 用戶組具可執(zhí)行權(quán)限
S_IROTH 00004 其他用戶具可讀取權(quán)限
S_IWOTH 00002 其他用戶具可寫入權(quán)限
S_IXOTH 00001 其他用戶具可執(zhí)行權(quán)限
上述的文件類型在POSIX中定義了檢查這些類型的宏定義:
S_ISLNK (st_mode) 判斷是否為符號連接
S_ISREG (st_mode) 是否為一般文件
S_ISDIR (st_mode)是否為目錄
S_ISCHR (st_mode)是否為字符裝置文件
S_ISBLK (s3e) 是否為先進先出
S_ISSOCK (st_mode) 是否為socket
若一目錄具有sticky位(S_ISVTX), 則表示在此目錄下的文件只能被該文件所有者, 此目錄所有者或root來刪除或改名. 執(zhí)行成功則返回0, 失敗返回-1, 錯誤代碼存于errno.
錯誤代碼:
ENOENT 參數(shù)file_name指定的文件不存在
ENOTDIR 路徑中的目錄存在但卻非真正的目錄
ELOOP 欲打開的文件有過多符號連接問題, 上限為16符號連接
EFAULT 參數(shù)buf為無效指針, 指向無法存在的內(nèi)存空間
EACCESS 存取文件時被拒絕
ENOMEM 核心內(nèi)存不足
ENAMETOOLONG 參數(shù)file_name的路徑名稱太長
應用舉例:
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
int main(void)
{
struct stat buf;
stat("/etc/passwd", &buf);
printf("etc/passwd file size = %d\n", buf.st_size);
return 0;
}
運行結(jié)果:
etc/passwd file size = 2529
symlink: 建立文件符號連接
頭文件: unistd.h
函數(shù)定義: int symlink(const char *oldpath, const char *newpath);
說明: symlink()以參數(shù)newpath指定的名稱來建立一個新的連接(符號連接)到參數(shù)oldpath所指定的已存在文件. 參數(shù)oldpath指定的文件不一定要存在, 如果參數(shù)newpath指定的名稱為一已存在的文件則不會建立連接. 成功則返回0, 失敗返回-1, 錯誤原因存于errno.
錯誤代碼:
EPERM 參數(shù)oldpath與newpath所指的文件系統(tǒng)不支持符號連接
EROFS 欲測試寫入權(quán)限的文件存在于只讀文件系統(tǒng)內(nèi)
EFAULT 參數(shù)oldpath或newpath指針超出可存取內(nèi)存空間
ENAMETOOLONG 參數(shù)oldpath或newpath太長
ENOMEM 核心內(nèi)存不足
EEXIST 參數(shù)newpath所指的文件名已存在
EMLINK 參數(shù)oldpath所指的文件已達到最大連接數(shù)目
ELOOP 參數(shù)pathname有過多符號連接問題
ENOSPC 文件系統(tǒng)的剩余空間不足
EIO I/O存取錯誤
telldir: 取得目錄流的讀取位置
頭文件: dirent.h
函數(shù)定義: off_t telldir(DIR *dir);
說明: telldir()返回參數(shù)dir目錄流目前的讀取位置. 此返回值代表距離目錄文件開頭的偏移量, 有錯誤發(fā)生時返回-1. EBADF表示參數(shù)dir為無效的目錄流.
truncate: 改變文件大小
頭文件: unistd.h
函數(shù)定義: int truncate(const char *path, off_t length);
說明: truncate()會將參數(shù)path指定的文件大小改為參數(shù)length指定的大小. 如果原來的文件大小比參數(shù)length大, 則超過的部分會被刪去. 執(zhí)行成功則返回0, 失敗返回-1, 錯誤原因存于errno.
錯誤代碼:
EACCESS 參數(shù)path所指定的文件無法存取。
EROFS 欲寫入的文件存在于只讀文件系統(tǒng)內(nèi)
EFAULT 參數(shù)path指針超出可存取內(nèi)存空間
EINVAL 參數(shù)path包含不合法字符
ENAMETOOLONG 參數(shù)path太長
ENOTDIR 參數(shù)path路徑并非一目錄
EISDIR 參數(shù)path指向一目錄
ETXTBUSY 參數(shù)path所指的文件為共享程序, 而且正被執(zhí)行中
ELOOP 參數(shù)path’有過多符號連接問題
EIO I/O存取錯誤
umask: 設(shè)置建立新文件時的權(quán)限遮罩
頭文件: sys/types.h sys/stat.h
函數(shù)定義: mode_t umask(mode_t mask);
說明: umask()會將系統(tǒng)umask值設(shè)成參數(shù)mask&0777后的值, 然后將先前的umask值返回. 在使用open()建立新文件時, 該參數(shù)mode并非真正建立文件的權(quán)限, 而是(mode&~umask)的權(quán)限值. 例如, 在建立文件時指定文件權(quán)限為0666, 通常umask值默認為022, 則該文件的真正權(quán)限則為0666&~022=0644, 也就是rw-r--r--. 此調(diào)用不會有錯誤值返回, 返回值為原先系統(tǒng)的umask值.
unlink: 刪除文件
頭文件: unistd.h
函數(shù)定義: int unlink(const char *pathname);
說明: unlink()會刪除參數(shù)pathname指定的文件. 如果該文件名為最后連接點, 但有其他進程打開了此文件, 則在所有關(guān)于此文件的文件描述詞皆關(guān)閉后才會刪除. 如果參數(shù)pathname為一符號連接, 則此連接會被刪除. 成功則返回0, 失敗返回-1, 錯誤原因存于errno.
錯誤代碼:
EROFS 文件存在于只讀文件系統(tǒng)內(nèi)
EFAULT 參數(shù)pathname指針超出可存取內(nèi)存空間
ENAMETOOLONG 參數(shù)pathname太長
ENOMEM 核心內(nèi)存不足
ELOOP 參數(shù)pathname有過多符號連接問題
EIO I/O存取錯誤
utime: 修改文件的存取時間和更改時間
頭文件: sys/types.h utime.h
函數(shù)定義: int utime(const char *filename, struct utimebuf *buf);
說明: utime()用來修改參數(shù)filename文件所屬的inode存取時間. 結(jié)構(gòu)utimbuf定義如下:
struct utimbuf{
time_t actime;
time_t modtime;
};
如果參數(shù)buf為空指針(NULL), 則該文件的存取時間和更改時間全部會設(shè)為目前時間. 執(zhí)行成功則返回0, 失敗返回-1, 錯誤代碼存于errno.
錯誤代碼:
EACCESS 存取文件時被拒絕, 權(quán)限不足
ENOENT 指定的文件不存在
utimes: 修改文件的存取時間和更改時間
頭文件: sys/types.h utime.h
函數(shù)定義: int utimes(char *filename, struct timeval *tvp);
說明: utimes()用來修改參數(shù)filename文件所屬的inode存取時間和修改時間, 結(jié)構(gòu)timeval定義如下:
struct timeval{
long tv_sec;
long tv_usec; /* 微妙 */
};
參數(shù)tvp指向兩個timeval結(jié)構(gòu)空間, 和utime()使用的utimebuf結(jié)構(gòu)比較, tvp.tc_sec則為utimbuf.actime, tvp.tv_sec為utimbuf.modtime. 執(zhí)行成功則返回0. 失敗返回-1, 錯誤代碼存于errno.
錯誤代碼:
EACCESS 存取文件時被拒絕, 權(quán)限不足
ENOENT 指定的文件不存在