Linux C 函數 文件及目錄函數

文件及目錄函數(37)node

chdir, chmod, chown, chroot
fchdir, fchmod, fchown, ftruncate
lchown, truncate,
linux

get_current_dir_name, getcwd, getwd數組

opendir, closedir, readir, scandir, seekdir, rewinddir, telldir
(mkdir, rmdir)
安全

fstat, lstat, stat數據結構

ftw, nftwapp

link, readlink, symlink, unlinksocket

access, alphasort, realpath, remove, rename, umaskide

utime, utimes函數


access: 判斷是否有存取文件的權限
頭文件: unistd.h
函數定義: int access(const char *pathname, int mode);
說明: access()會檢查是否能夠讀/寫某一已存在的文件. 參數mode有幾種狀況組合, R_OK, W_OK, X_OK和F_OK. R_OK, W_OK與X_OK用來檢查文件是否具備讀取, 寫入和執行的權限. F_OK則是用來判斷該文件是否存在. 因爲access()只做權限的核查, 並不理會文件形態或文件內容, 所以, 若是一目錄表示爲"可寫入", 表示能夠在該目錄中創建新文件等操做, 而非意味此目錄能夠被當作文件處理. 若全部欲查覈的權限都經過了檢查則返回0值, 表示成功, 只要有一權限被禁止則返回-1.
錯誤代碼: 
   EACCESS      參數pathname所指定的文件不符合所要求測試的權限
   EROFS        欲測試寫入權限的文件存在於只讀文件系統內
   EFAULT       參數pathname指針超出可存取內存空間
   EINVAL       參數mode不正確
   ENAMETOOLONG 參數pathname太長
   ENOTDIR      參數pathname爲一目錄
   ENOMEM       核心內存不足
   ELOOP        參數pathname有過多符號鏈接問題
   EIO          I/O存取錯誤
附加說明: 使用access()做用戶認證方面的判斷要特別當心, 例如在access()後再作open()的空文件可能會形成系統安全上的問題.
應用舉例:
#include <stdio.h>
#include <unistd.h>
int main(void)
{
if(access("/etc/passwd", R_OK) == 0)
{
   printf("/etc/passwd can be read\n");
}
return 0;
}
運行結果:
/etc/passwd can be read
測試

alphasort: 依字母順序排序目錄結構
頭文件: dirent.h
定義函數: int alphasort(const struct dirent **a, const struct dirent **b);
說明: alphasort()爲scandir()最後調用的函數, 詳細說明請參考scandir().
應用舉例: 
/* 讀取/目錄下的目錄結構, 並依字母順尋排列 */
#include <stdio.h>
#include <dirent.h>
int main(void)
{
struct dirent **namelist;
int i, total;
total = scandir("/", &namelist, 0, alphasort);
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;
}
運行結果:
.
..
.autofsck
bin
boot
...
total = 24

chdir: 改變當前的工做目錄
頭文件: unistd.h
函數定義: int chdir(const char *path);
說明: chdir()用來將當前的工做目錄該變成爲參數path所指的目錄. 若成功返回0, 失敗返回-1, errno爲錯誤代碼.

chmod: 改變文件的權限
頭文件: sys/types.h sys/stat.h
函數定義: int chmod(const char *path, mode_t mode);
說明: chmod()會依參數mode權限來更改參數path指定文件的權限. 參數mode有下列數種組合:
   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   文件全部者具可讀取權限
   S_IWUSR(S_IWRITE) 00200   文件全部者具可寫入權限
   S_IXUSR(S_IEXEC) 00100   文件全部者具可執行權限
   S_IRGRP           00040   用戶組具可讀取權限
   S_IWGRP           00020   用戶組具可寫入權限
   S_IXGRP           00010   用戶組具可執行權限
   S_IROTH           00004   其餘用戶具可讀取權限
   S_IWOTH           00002   其餘用戶具可寫入權限
   S_IXOTH           00001   其餘用戶具可執行權限
只有該文件的全部者或有效用戶識別碼爲0, 才能夠修改該文件權限. 基於系統安全, 若是欲將數據寫入一執行文件, 而該執行文件具備S_ISUID或S_ISGID權限, 則這兩個位會被清除. 若是一目錄具備S_ISUID位權限, 表示在此目錄下只有該文件的全部者或root能夠刪除該文件. 若權限改變成功返回0, 失敗返回-1, 錯誤緣由存於erron.
錯誤代碼:
   EPERM    進程的有效用戶識別碼與欲修改權限的文件擁有者不一樣, 並且也不具root權限. 
   EACCESS 參數path所指定的文件沒法存取
   EROFS    欲寫入權限的文件存在於只讀文件系統內
   EFAULT   參數path指針超出可存取內存空間
   EINVAL   參數mode不正確
   ENAMETOOLONG 參數path太長
   ENOENT   指定的文件不存在
   ENOTDIR 參數path路徑並不是一目錄
   ENOMEM   核心內存不足
   ELOOP    參數path有過多符號鏈接問題
   EIO      I/O存取錯誤

chown: 改變文件的全部者
頭文件: sys/types.h unistd.h
函數定義: int chown(const char *path, uid_t owner, gid_t group);
說明: chown()會將參數path指定文件的全部者變動爲參數owner表明的用戶, 而將該文件的組變動爲參數group組. 若是參數owner或group爲-1, 對應的全部者或組不會有所改變. root與文件全部者皆可改變文件組, 但全部者必須是參數group組的成員. 當root用chown()改變文件全部者或組時, 該文件若具備S_ISUID或S_ISGID權限, 則會清除此權限位, 此外若是具備S_ISGID權限但不具S_IXGRP位, 則該文件會被強制鎖定, 文件模式會保留. 成功則返回0, 失敗返回-1, 錯誤緣由存於errno. 錯誤代碼同chmod().

chroot: 改變根目錄
頭文件: unistd.h
函數定義: int chroot(const char *path);
說明: chroot()用來改變根目錄爲參數path所指定的目錄. 只有超級用戶才容許改變根目錄, 子進程將繼承新的根目錄. 調用成功則返回0, 失敗則返-1, 錯誤代碼存於errno.
錯誤代碼: 
   EPERM    權限不足, 沒法改變根目錄
   EFAULT   參數path指針超出可存取內存空間
   ENAMETOOLONG 參數path太長
   ENOTDIR 路徑中的目錄存在但卻非真正的目錄
   EACCESS 存取目錄時被拒絕
   ENOMEM   核心內存不足
   ELOOP    參數path有過多符號鏈接問題
   EIO      I/O存取錯誤
應用舉例:
#include <stdio.h>
#include <unistd.h>
int main(void)
{
/* 將根目錄改成/tmp ,並將工做目錄切換至/tmp */
chroot("/tmp");
chdir("/");
return 0;
}

closedir: 關閉目錄
頭文件: sys/types.h dirent.h
函數定義: int closedir(DIR *dir);
說明: closedir()關閉參數dir所指的目錄流. 關閉成功則返回0, 失敗返回-1, 錯誤緣由存於errno中. EBADF參數dir爲無效的目錄流.

fchdir: 改變當前的工做目錄
頭文件: unistd.h
函數定義: int fchdir(int fd);
說明: fchdir()用來將當前的工做目錄改變成以參數fd所指的文件描述詞. 執行成功則返回0, 失敗返回-1, errno爲錯誤代碼.

fchmod: 改變文件的權限
頭文件: sys/types.h sys/stat.h
函數定義: int fdmod(int fildes, mode_t mode);
說明: fchmod()會依參數mode權限來更改參數fildes所指文件的權限. 參數fildes爲已打開文件的文件描述詞. 參數mode請參考chmod(). 權限改變成功則返回0, 失敗返回-1, 錯誤緣由存於errno. 
錯誤代碼: 
   EBADF 參數fildes爲無效的文件描述詞
   EPERM 進程的有效用戶識別碼與欲修改權限的文件全部者不一樣, 並且也不具root權限
   EROFS 欲寫入權限的文件存在於只讀文件系統內
   EIO    I/O存取錯誤

fchown: 改變文件的全部者
頭文件: sys/types.h unistd.h
函數定義: int fchown(int fd, uid_t owner, gid_t group);
說明: fchown()會將參數fd指定文件的全部者變動爲參數owner表明的用戶, 而將該文件的組變動爲參數group組. 若是參數owner或group爲-1, 對映的全部者或組有所改變. 參數fd爲已打開的文件描述詞. 當root用fchown()改變文件全部者或組時, 該文件若具S_ISUID或S_ISGID權限, 則會清除此權限位. 成功則返回0, 失敗則返回-1, 錯誤緣由存於errno.
錯誤代碼: 
   EBADF   參數fd文件描述詞爲無效的或該文件已關閉
   EPERM   進程的有效用戶識別碼與欲修改權限的文件全部者不一樣, 並且也不具root權限, 或是參數owner, group不正確
   EROFS   欲寫入的文件存在於只讀文件系統內
   ENOENT 指定的文件不存在
   EIO     I/O存取錯誤

fstat: 由文件描述詞取得文件狀態
頭文件: sys/stat.h unistd.h
函數定義: int fstat(int fildes, struct stat *buf);
說明: fstat()用來將參數fildes所指的文件狀態, 複製到參數buf所指的結構中(struct stat). fstat()與stat()做用徹底相同, 不一樣處在於傳入的參數爲已打開的文件描述詞. 詳細內容請參考stat(). 執行成功則返回0, 失敗返回-1, 錯誤代碼存於errno.

ftruncate: 改變文件大小
頭文件: unistd.h
函數定義: int ftruncate(int fd, off_t length);
說明: ftruncate()會將參數fd指定的文件大小改成參數length指定的大小. 參數fd爲已打開的文件描述詞, 並且必須是以寫入模式打開的文件. 若是原來的文件大小比參數length大, 則超過的部分會被刪去. 執行成功則返回0, 失敗返回-1, 錯誤緣由存於errno.
錯誤代碼: 
   EBADF    參數fd文件描述詞爲無效的或該文件已關閉
   EINVAL 參數fd爲一socket並不是文件, 或是該文件並不是以寫入模式打開

ftw: 遍歷目錄樹
頭文件: ftw.h
函數定義: int ftw(const char *dir, int (*fn)(const char *file, const struct stat *sb, int flag), int depth);
說明: ftw()會從參數dir指定的目錄開始, 往下一層層地遞歸式遍歷子目錄. 每進入一個目錄, 便會調用參數*fn定義的函數來處理. ftw()會傳三個參數給fn(), 第一個參數*file指向當時所在的目錄路徑, 第二個參數是*sb, 爲stat結構指針(該結構的定義請參考stat()), 第三個參數爲旗標, 有下面幾種可能值:
   FTW_F    通常文件
   FTW_D    目錄
   FTW_DNR 不可讀取的目錄. 此目錄如下將不被遍歷
   FTW_SL   符號鏈接
   FTW_NS   沒法取得stat結構數據, 有多是權限問題
最後一個參數depth表明ftw()在進行遍歷目錄時可同時打開的文件數. ftw()在遍歷時每一層目錄至少須要一個文件描述詞, 若是遍歷時用完了depth所給予的限制數目, 整個遍歷將因不斷地關閉文件和打開文件操做而顯得緩慢. 若是要結束ftw()的遍歷, fn()只需返回一非零值便可, 此值同時也會是ftw()的返回值, 不然ftw()會試着走完全部的目錄, 而後返回0. 遍歷中斷則返回fn()函數的返回值, 所有遍歷完則返回0. 若有錯誤發生則返回-1.
附加說明: 因爲ftw()會動態配置內存使用, 請使用正常方式(fn函數返回非0值)來中斷遍歷, 不要在fn函數中使用longjmp().
應用舉例:
/* 列出/etc/X11目錄下的子目錄 */
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ftw.h>
int fn(const char *file, const struct stat* sb, int flag)
{
if(flag == FTW_D)
{
   printf("%s -- directory\n", file);
}
return 0;
}
int main(void)
{
ftw("/etc/X11", fn, 500);
return 0;
}
運行結果:
/etc/X11 -- directory
/etc/X11/xinit -- directory
/etc/X11/xinit/xinitrc.d -- directory
/etc/X11/xinit/Xclients.d -- directory
/etc/X11/xinit/xinput.d -- directory
/etc/X11/xdm -- directory
/etc/X11/applnk -- directory
/etc/X11/twm -- directory

get_current_dir_name: 取得當前的工做目錄
頭文件: unistd.h
函數定義: char *get_current_dir_name(void);
說明: 此函數會返回一字符串指針, 指向目前的工做目錄絕對路徑字符串. 執行成功返回字符串指針, 失敗返回NULL, 錯誤代碼存於errno.
getcwd: 取得當前的工做目錄
頭文件: unistd.h
函數定義: char *getcwd(char *buf, size_t size);
說明: getcwd()會將當前的工做目錄絕對路徑複製到參數buf所指的內存空間, 參數size爲buf的空間大小. 在調用此函數時, buf所指的內存空間要足夠大, 若工做目錄絕對路徑的字符串長度超過參數size大小, 則回值NULL, errno的值則爲ERANGE. 假若參數buf爲NULL, getcwd()會依參數size的大小自動配置內存(使用malloc()), 若是參數size也爲0, 則getcwd()會依工做目錄絕對路徑的字符串程度來決定所配置的內存大小, 進程能夠在使用完此字符串後利用free()來釋放此空間. 執行成功則將結果複製到參數buf所指的內存空間, 或是返回自動配置的字符串指針. 失敗返回NULL, 錯誤代碼存於errno.
getwd: 取得當前的工做目錄
頭文件: unistd.h
函數定義: char *getwd(char *buf);
說明: getwd()會將當前的工做目錄絕對路徑複製到參數buf所指的內存空間, 而後將此路徑字符串指針返回. 執行成功則將結果複製到參數buf所指的內存空間, 失敗返回NULL, 錯誤代碼存於errno.
應用舉例:
#include <stdio.h>
#include <unistd.h>
int main(void)
{
char *ptr1, *ptr2;
char buf[80];
ptr1 = get_current_dir_name();
printf("%s\n", ptr1);
getcwd(buf, sizeof(buf));
printf("%s\n", buf);
ptr2 = getcwd(NULL, 0);
printf("%s\n", ptr2);
free(ptr2);
getwd(buf);
printf("%s\n", buf);
return 0;
}
運行結果:
/root/c-function
/root/c-function
/root/c-function
/root/c-function

lchown: 改變文件的全部者
頭文件: sys/types.h unistd.h
函數定義: int lchown(const char *path, uid_t ownwer, gid_t group);
說明: lchown()會將參數path指定文件的全部者變動爲參數owner表明的用戶, 而將該文件的組變動爲參數group組. 若是參數owner或group爲-1, 對應的全部者活組不會有所改變. 當root用lchown()改變文件全部者或組時, 該文件若具S_ISUID或S_ISGID權限, 則會清除此權限位. lchown()與chown不一樣之處在於, 若是參數path指定的文件爲一符號鏈接(symbolic link), lchown()是改變鏈接自己的全部者或組, chown()則是改變鏈接所指向的文件全部者或組. 成功則返回0, 失敗返回-1, 錯誤緣由在於errno.
錯誤代碼:
   EPERM     進程的有效用戶識別碼與欲修改權限的文件擁有者不一樣, 並且也不具root權限, 或是參數owner/group不正確
   EACCESS   參數path所指定的文件沒法存取
   EROFS     欲寫入的文件存在於只讀文件系統內
   EFAULT    參數path指針超出可存取內存空間
   ENAMETOOLONG 參數path太長
   ENOENT    參數path指定的文件不存在
   ENOTDIR   參數path路徑並不是一目錄
   ENOMEM    核心內存不足
   ELOOP     參數path有過多符號鏈接問題
   EIO       I/O存取錯誤

 

link: 創建文件硬鏈接
頭文件: unistd.h
函數定義: int link(const char *oldpath, const char *newpath);
說明: link()以參數newpath指定的名稱來創建一個新的鏈接(硬鏈接)到參數oldpath所指定的已存在文件. 若是參數newpath指定的名稱爲一已存在的文件則不會創建鏈接. 成功則返回0, 失敗返回-1, 錯誤緣由存於errno.
錯誤代碼:
   EXDEV   參數oldpath與newpath不是創建在同一文件系統
   EPERM   參數oldpath與newpath所指的文件系統不支持硬鏈接
   EROFS   文件存在於只讀文件系統內
   EFAULT 參數oldpath或newpath指針超出可存取內存空間
   ENAMETOLLONG   參數oldpath或newpath太長
   ENOMEM 核心內存不足
   EEXIST 參數newpath所指的文件名已存在
   EMLINK 參數oldpath所指的文件已達最大鏈接數目
   ELOOP   參數pathname有過多符號鏈接問題
   ENOSPC 文件系統的剩餘空間不足
   EIO     I/O存取錯誤
附加說明: link()所創建的硬鏈接沒法跨越不一樣文件系統, 若是須要請改用symlink().

lstat: 由文件描述詞取得文件狀態
頭文件: sys/stat.h unistd.h
函數定義: int lstat(const char *file_name, struct stat *buf);
說明: lstat()與stat()做用徹底相同, 都是取得參數file_name所指的文件狀態, 其差異在於, 當文件爲符號鏈接時, lstat()會返回該link自己的狀態. 詳細內容請參考stat(). 執行成功則返回0, 失敗返回-1, 錯誤代碼存於errno.

nftw: 遍歷目錄樹
頭文件: ftw.h
函數定義: int nftw(const char *dir, int (*fn)(const char *file, const struct stat *sb, int flag, struct FTW *s), depth, int flags);
說明: nftw()與ftw()很像, 都是從參數dir指定的目錄開始, 往下一層層地遞歸式遍歷子目錄. 每進入一個目錄, 便會調用參數*fn定義的函數來處理. nftw()會傳四個參數給fn(), 第一個參數*file指向當時所在的目錄路徑, 第二個參數是*sb, 爲stat結構指針(結構定義請參考stat()), 第三個參數爲旗標, 有如下幾種可能:
   FTW_F    通常文件
   FTW_D    目錄
   FTW_DNR 不可讀取的目錄. 此目錄如下將不被遍歷
   FTW_SL   符號鏈接
   FTW_NS   沒法取得stat結構數據, 有多是權限問題
   FTW_DP   目錄, 並且其子目錄都已被遍歷過了.
   FTW_SLN 符號鏈接, 但鏈接不存在文件
fn()的第四個參數是FTW結構, 定義以下:
struct FTW{
int base;
int level;
}
level表明遍歷當時的深度, nftw()第三個參數depth表明nftw()在進行遍歷目錄時可同時打開的文件數. ftw()在遍歷時每一層目錄至少須要一個文件描述詞, 若是遍歷時用完了depth所給予的限制數目, 整個遍歷將因不斷地關閉文件和打開文件操做而顯得緩慢. nftw()最後一個參數flags用來指定遍歷時的動做, 能夠指定下列的操做或用OR組合:
   FTW_CHDIR   在讀目錄以前用chdir()移到此目錄
   FTW_DEPTH   執行深度優先搜索. 在遍歷此目錄前先將全部子目錄遍歷完
   FTW_MOUNT   遍歷時不要跨越到其餘文件系統
   FTW_PHYS    不要遍歷符號鏈接的目錄. 預設會遍歷符號鏈接目錄
若是要結束ftw()的遍歷, fn()只需返回一非零值便可, 此值同時也會是ftw()的返回值, 不然ftw()會試着走完全部的目錄, 而後返回0. 遍歷中斷則返回fn()函數的返回值, 所有遍歷完則返回0. 若有錯誤發生則返回-1.
附加說明: 因爲ftw()會動態配置內存使用, 請使用正常方式(fn函數返回非0值)來中斷遍歷, 不要在fn函數中使用longjmp().

opendir: 打開目錄
頭文件: sys/types.h dirent.h
函數定義: DIR *opendir(const char *name);
說明: opendir()用來打開參數name指定的目錄, 並返回DIR*形態的目錄流, 和open()相似, 接下來對目錄的讀取和搜索都要使用此返回值. 成功則返回DIR*型態的目錄流, 打開失敗則返回NULL.
錯誤代碼:
   EACCESS 權限不足
   EMFILE   已達到進程可同時打開的文件數上限
   ENFILE   已達到系統可同時打開的文件數上限
   ENOTDIR 參數name非真正的目錄
   ENOENT   參數name指定的目錄不存在, 或是參數name爲一空字符串
   ENOMEM   核心內存不足

readdir: 讀取目錄
頭文件: sys/types.h dirent.h
定義函數: struct dirent *readdir(DIR *dir);
說明: readdir()返回參數dir目錄流的下個目錄進入點. 結構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   文件名
成功則返回下個目錄進入點, 有錯誤發生或讀取到目錄文件尾則返回NULL. EBADF參數dir爲無效的目錄流.
應用舉例:
/* 讀取/etc/rc.d目錄文件結構, 而後顯示目錄下的文件 */
#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;
}
運行結果:
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
函數定義: int readlink(const char *path, char *buf, size_t bufsize);
說明: readlink()會將參數path的符號鏈接內容存到參數buf所指的內存空間, 返回的內容不是以NULL做字符串結尾, 但會將字符串的字符數返回. 若參數bufsiz小於符號鏈接的內容長度, 過長的內容會被截斷. 執行成功則傳符號鏈接所指的文件路徑字符串, 失敗則返回-1, 錯誤代碼存於errno.
錯誤代碼: 
   EACCESS 取文件時被拒絕, 權限不夠
   EINVAL   參數bufsiz爲負數
   EIO      I/O存取錯誤
   ELOOP    欲打開的文件有過多符號鏈接問題
   ENAMETOOLONG 參數path的路徑名稱太長
   ENOENT   參數path所指定的文件不存在
   ENOMEM   核心內存不足
   ENOTDIR 參數path路徑中的目錄存在但卻非真正的目錄

realpath: 將相對目錄路徑轉換成絕對路徑
頭文件: limits.h stdlib.h
函數定義: char *realpath(const char *path, char *resolved_path);
說明: realpath()用來將參數path所指的相對路徑轉換成絕對路徑存於參數resolved_path所指的字符串數組中. 若是轉換成功則返回指向resolved_path的指針. 失敗返回NULL, 錯誤代碼存於errno.

remove: 刪除文件或目錄
頭文件: stdio.h
函數定義: int remove(const char *pathname);
說明: remove()會刪除參數pathname指定的文件. 若是參數pathname爲一文件, 則調用unlink()處理, 若參數pathname爲一目錄, 則調用rmdir()來處理. 請參考unlink()與rmdir(). 成功則返回0, 失敗則返回-1, 錯誤緣由存於errno.
錯誤代碼: 
   EROFS    欲寫入的文件存在於只讀文件系統內
   EFAULT   參數pathname指針超出可存取內存空間
   ENAMETOOLONG   參數pathname太長
   ENOMEM   核心內存不足
   ELOOP    參數pathname有過多符號鏈接問題
   EIO      I/O存取錯誤.

rename: 更改文件名或位置
頭文件: stdio.h
函數定義: int rename(const char *oldpath, const char *newpath);
說明: rename()會將參數oldpath所指定的文件名稱改成參數newpath所指的文件名稱. 若newpath所指定的文件已存在, 則會被刪除. 執行成功則返回0, 失敗返回-1, 錯誤緣由存於errno.

rewinddir: 將讀取目錄的位置設爲開頭位置
頭文件: sys/types.h dirent.h
函數定義: void rewinddir(DIR *dir);
說明: rewinddir()用來設置參數dir目錄流目前的讀取位置爲原來開頭的讀取位置. EBADF表示dir爲無效的目錄流.

scandir: 讀取特定的目錄數據
頭文件: dirent.h
函數定義: int scandir(const char *dir, struct dirent ***namelist, int (*select)(const struct dirent *), int (*compar)(const struct dirent**, const struct dirent**));
說明: scandir()會掃描參數dir指定的目錄文件, 經由參數select指定的函數來挑選目錄結構至參數namelist數組中, 最後在調用參數compar指定的函數來排序namelist數組中的目錄數據. 每次從目錄文件中讀取一個目錄結構後便將此結構傳給參數select所指的函數, select函數若不想要將此目錄機構複製到namelist數組就返回0, 若select爲空指針則表明選擇全部的目錄結構. scandir()會調用qsort()來排序數據, 參數compar則爲qsort()的參數, 如果要排列目錄名稱字母則可以使用alphasort(). 結構dirent定義請參考readdir(). 成功則返回複製到namelist數組中的數據結構數目, 有錯誤發生則返回-1. ENOMEM表示核心內存不足.
應用舉例:
/* 讀取/目錄下文件名長度大於5的目錄結構 */
#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;
}
運行結果:
selinux
total = 3
.autofsck
total = 3
lost+found
total = 3

seekdir: 設置下回讀取目錄的位置
頭文件: dirent.h
函數定義: void seekdir(DIR *dir, off_t offset);
說明: seekdir()用來設置參數dir目錄流目前的讀取位置, 在調用readdir()時便今後新位置開始讀取. 參數offset表明距離目錄文件開頭的偏移量. EBADF表示參數dir爲無效路徑.

stat: 取得文件狀態
頭文件: sys/stat.h unistd.h
函數定義: int stat(const char *file_name, struct stat *buf);
說明: stat()用來將參數file_name所指的文件狀態, 複製到參數buf所指的結構中. 下面是struct stat內各參數的說明:
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    文件的設備編號
st_ino    文件的i-node
st_mode   文件的類型和存取的權限
st_nlink 連到該文件的硬鏈接數目, 剛創建的文件值爲1
st_uid    文件全部者的用戶識別碼
st_gid    文件全部者的組識別碼
st_rdev   若此文件爲裝置設備文件, 則爲其設備編號
st_size   文件大小, 以字節計算
st_blksize 文件系統的I/O緩衝區大小
st_blcoks 佔用文件區塊的個數, 每一區塊大小爲512個字節
st_atime 文件最近一次被存取或被執行的時間, 通常只有在用mknod, utime, read, write與tructate時改變
st_mtime 文件最後一次被修改的時間, 通常只有在用mknod, utime和write時纔會改變
st_ctime i-node最近一次被更改的時間, 此參數會在文件全部者, 組, 權限被更改時更新
先前所描述的st_mode則定義了下列數種狀況:
   S_IFMT    0170000 文件類型的位遮罩
   S_IFSOCK 0140000 scoket
   S_IFLNK   0120000 符號鏈接
   S_IFREG   0100000 通常文件
   S_IFBLK   0060000 區塊裝置
   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 文件全部者具可讀取權限
   S_IWUSR(S_IWRITE) 00200 文件全部者具可寫入權限
   S_IXUSR(S_IEXEC)   00100 文件全部者具可執行權限
   S_IRGRP     00040 用戶組具可讀取權限
   S_IWGRP     00020 用戶組具可寫入權限
   S_IXGRP     00010 用戶組具可執行權限
   S_IROTH     00004 其餘用戶具可讀取權限
   S_IWOTH     00002 其餘用戶具可寫入權限
   S_IXOTH     00001 其餘用戶具可執行權限
上述的文件類型在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來刪除或更名. 執行成功則返回0, 失敗返回-1, 錯誤代碼存於errno.
錯誤代碼: 
   ENOENT   參數file_name指定的文件不存在
   ENOTDIR 路徑中的目錄存在但卻非真正的目錄
   ELOOP    欲打開的文件有過多符號鏈接問題, 上限爲16符號鏈接
   EFAULT   參數buf爲無效指針, 指向沒法存在的內存空間
   EACCESS 存取文件時被拒絕
   ENOMEM   核心內存不足
   ENAMETOOLONG 參數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;
}
運行結果:
etc/passwd file size = 2529

symlink: 創建文件符號鏈接
頭文件: unistd.h
函數定義: int symlink(const char *oldpath, const char *newpath);
說明: symlink()以參數newpath指定的名稱來創建一個新的鏈接(符號鏈接)到參數oldpath所指定的已存在文件. 參數oldpath指定的文件不必定要存在, 若是參數newpath指定的名稱爲一已存在的文件則不會創建鏈接. 成功則返回0, 失敗返回-1, 錯誤緣由存於errno.
錯誤代碼:
   EPERM   參數oldpath與newpath所指的文件系統不支持符號鏈接
   EROFS   欲測試寫入權限的文件存在於只讀文件系統內
   EFAULT 參數oldpath或newpath指針超出可存取內存空間
   ENAMETOOLONG 參數oldpath或newpath太長
   ENOMEM 核心內存不足
   EEXIST 參數newpath所指的文件名已存在
   EMLINK 參數oldpath所指的文件已達到最大鏈接數目
   ELOOP   參數pathname有過多符號鏈接問題
   ENOSPC 文件系統的剩餘空間不足
   EIO     I/O存取錯誤

telldir: 取得目錄流的讀取位置
頭文件: dirent.h
函數定義: off_t telldir(DIR *dir);
說明: telldir()返回參數dir目錄流目前的讀取位置. 此返回值表明距離目錄文件開頭的偏移量, 有錯誤發生時返回-1. EBADF表示參數dir爲無效的目錄流.

truncate: 改變文件大小
頭文件: unistd.h
函數定義: int truncate(const char *path, off_t length);
說明: truncate()會將參數path指定的文件大小改成參數length指定的大小. 若是原來的文件大小比參數length大, 則超過的部分會被刪去. 執行成功則返回0, 失敗返回-1, 錯誤緣由存於errno. 
錯誤代碼: 
   EACCESS   參數path所指定的文件沒法存取。
   EROFS     欲寫入的文件存在於只讀文件系統內
   EFAULT    參數path指針超出可存取內存空間
   EINVAL    參數path包含不合法字符
   ENAMETOOLONG 參數path太長
   ENOTDIR   參數path路徑並不是一目錄
   EISDIR    參數path指向一目錄
   ETXTBUSY 參數path所指的文件爲共享程序, 並且正被執行中
   ELOOP     參數path’有過多符號鏈接問題
   EIO       I/O存取錯誤

umask: 設置創建新文件時的權限遮罩
頭文件: sys/types.h sys/stat.h
函數定義: mode_t umask(mode_t mask);
說明: umask()會將系統umask值設成參數mask&0777後的值, 而後將先前的umask值返回. 在使用open()創建新文件時, 該參數mode並不是真正創建文件的權限, 而是(mode&~umask)的權限值. 例如, 在創建文件時指定文件權限爲0666, 一般umask值默認爲022, 則該文件的真正權限則爲0666&~022=0644, 也就是rw-r--r--. 此調用不會有錯誤值返回, 返回值爲原先系統的umask值.

unlink: 刪除文件
頭文件: unistd.h
函數定義: int unlink(const char *pathname);
說明: unlink()會刪除參數pathname指定的文件. 若是該文件名爲最後鏈接點, 但有其餘進程打開了此文件, 則在全部關於此文件的文件描述詞皆關閉後纔會刪除. 若是參數pathname爲一符號鏈接, 則此鏈接會被刪除. 成功則返回0, 失敗返回-1, 錯誤緣由存於errno.
錯誤代碼: 
   EROFS   文件存在於只讀文件系統內
   EFAULT 參數pathname指針超出可存取內存空間
   ENAMETOOLONG 參數pathname太長
   ENOMEM 核心內存不足
   ELOOP   參數pathname有過多符號鏈接問題
   EIO     I/O存取錯誤

utime: 修改文件的存取時間和更改時間
頭文件: sys/types.h utime.h
函數定義: int utime(const char *filename, struct utimebuf *buf);
說明: utime()用來修改參數filename文件所屬的inode存取時間. 結構utimbuf定義以下:
struct utimbuf{
time_t actime;
time_t modtime;
};
若是參數buf爲空指針(NULL), 則該文件的存取時間和更改時間所有會設爲目前時間. 執行成功則返回0, 失敗返回-1, 錯誤代碼存於errno.
錯誤代碼: 
   EACCESS 存取文件時被拒絕, 權限不足
   ENOENT   指定的文件不存在

utimes: 修改文件的存取時間和更改時間 頭文件: sys/types.h utime.h 函數定義: int utimes(char *filename, struct timeval *tvp); 說明: utimes()用來修改參數filename文件所屬的inode存取時間和修改時間, 結構timeval定義以下: struct timeval{ long tv_sec; long tv_usec; /* 微妙 */ }; 參數tvp指向兩個timeval結構空間, 和utime()使用的utimebuf結構比較, tvp.tc_sec則爲utimbuf.actime, tvp.tv_sec爲utimbuf.modtime. 執行成功則返回0. 失敗返回-1, 錯誤代碼存於errno.  錯誤代碼:     EACCESS 存取文件時被拒絕, 權限不足    ENOENT   指定的文件不存在

相關文章
相關標籤/搜索