一些檔案操作函式(啥啥啥)
close(關閉檔案)
相關函式 open,fcntl,shutdown,unlink,fclose
表頭檔案 #include<unistd.h>
定義函式 int close(int fd);
函式說明 當使用完檔案後若已不再需要則可使用close()關閉該檔案,二close()會讓資料寫回磁碟,並釋放該檔案所佔用的資源。引數fd為先前由open()或creat()所返回的檔案描述詞。
返回值 若檔案順利關閉則返回0,發生錯誤時返回-1。
錯誤程式碼 EBADF 引數fd 非有效的檔案描述詞或該檔案已關閉。
附加說明 雖然在程序結束時,系統會自動關閉已開啟的檔案,但仍建議自行關閉檔案,並確實檢查返回值。
範例 參考open()
creat(建立檔案)
相關函式 read,write,fcntl,close,link,stat,umask,unlink,fopen
表頭檔案 #include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
定義函式 int creat(const char * pathname, mode_tmode);
函式說明 引數pathname指向欲建立的檔案路徑字串。Creat()相當於使用下列的呼叫方式呼叫open()
open(const char * pathname ,(O_CREAT|O_WRONLY|O_TRUNC));
錯誤程式碼 關於引數mode請參考open()函式。
返回值 creat()會返回新的檔案描述詞,若有錯誤發生則會返回-1,並把錯誤程式碼設給errno。
EEXIST 引數pathname所指的檔案已存在。
EACCESS 引數pathname 所指定的檔案不符合所要求測試的許可權
EROFS 欲開啟寫入許可權的檔案存在於只讀檔案系統內
EFAULT 引數pathname 指標超出可存取的記憶體空間
EINVAL 引數mode 不正確。
ENAMETOOLONG 引數pathname太長。
ENOTDIR 引數pathname為一目錄
ENOMEM 核心記憶體不足
ELOOP 引數pathname有過多符號連線問題。
EMFILE 已達到程序可同時開啟的檔案數上限
ENFILE 已達到系統可同時開啟的檔案數上限
附加說明 creat()無法建立特別的裝置檔案,如果需要請使用mknod()。
範例 請參考open()。
dup(複製檔案描述詞)
相關函式 open,close,fcntl,dup2
表頭檔案 #include<unistd.h>
定義函式 int dup (int oldfd);
函式說明 dup()用來複制引數oldfd所指的檔案描述詞,並將它返回。此新的檔案描述詞和引數oldfd指的是同一個檔案,共享所有的鎖定、讀寫位置和各項許可權或旗標。例如,當利用lseek()對某個檔案描述詞作用時,另一個檔案描述詞的讀寫位置也會隨著改變。不過,檔案描述詞之間並不共享close-on-exec旗標。
返回值 當複製成功時,則返回最小及尚未使用的檔案描述詞。若有錯誤則返回-1,errno會存放錯誤程式碼。錯誤程式碼EBADF引數fd非有效的檔案描述詞,或該檔案已關閉。
dup2(複製檔案描述詞)
相關函式 open,close,fcntl,dup
表頭檔案 #include<unistd.h>
定義函式 int dup2(int odlfd,int newfd);
函式說明 dup2()用來複制引數oldfd所指的檔案描述詞,並將它拷貝至引數newfd後一塊返回。若引數newfd為一已開啟的檔案描述詞,則newfd所指的檔案會先被關閉。dup2()所複製的檔案描述詞,與原來的檔案描述詞共享各種檔案狀態,詳情可參考dup()。
返回值 當複製成功時,則返回最小及尚未使用的檔案描述詞。若有錯誤則返回-1,errno會存放錯誤程式碼。
附加說明 dup2()相當於呼叫fcntl(oldfd,F_DUPFD,newfd);請參考fcntl()。
錯誤程式碼 EBADF 引數fd 非有效的檔案描述詞,或該檔案已關閉
fcntl(檔案描述詞操作)
相關函式 open,flock
表頭檔案 #include<unistd.h>
#include<fcntl.h>
定義函式 int fcntl(int fd , int cmd);
int fcntl(int fd,int cmd,long arg);
int fcntl(int fd,int cmd,struct flock * lock);
函式說明 fcntl()用來操作檔案描述詞的一些特性。引數fd代表欲設定的檔案描述詞,引數cmd代表欲操作的指令。
有以下幾種情況:
F_DUPFD用來查詢大於或等於引數arg的最小且仍未使用的檔案描述詞,並且複製引數fd的檔案描述詞。執行成功則返回新複製的檔案描述詞。請參考dup2()。F_GETFD取得close-on-exec旗標。若此旗標的FD_CLOEXEC位為0,代表在呼叫exec()相關函式時檔案將不會關閉。
F_SETFD 設定close-on-exec 旗標。該旗標以引數arg 的FD_CLOEXEC位決定。
F_GETFL 取得檔案描述詞狀態旗標,此旗標為open()的引數flags。
F_SETFL 設定檔案描述詞狀態旗標,引數arg為新旗標,但只允許O_APPEND、O_NONBLOCK和O_ASYNC位的改變,其他位的改變將不受影響。
F_GETLK 取得檔案鎖定的狀態。
F_SETLK 設定檔案鎖定的狀態。此時flcok 結構的l_type 值必須是F_RDLCK、F_WRLCK或F_UNLCK。如果無法建立鎖定,則返回-1,錯誤程式碼為EACCES 或EAGAIN。
F_SETLKW F_SETLK 作用相同,但是無法建立鎖定時,此呼叫會一直等到鎖定動作成功為止。若在等待鎖定的過程中被訊號中斷時,會立即返回-1,錯誤程式碼為EINTR。引數lock指標為flock 結構指標,定義如下
struct flcok
{
short int l_type; /* 鎖定的狀態*/
short int l_whence;/*決定l_start位置*/
off_t l_start; /*鎖定區域的開頭位置*/
off_t l_len; /*鎖定區域的大小*/
pid_t l_pid; /*鎖定動作的程序*/
};
l_type 有三種狀態:
F_RDLCK 建立一個供讀取用的鎖定
F_WRLCK 建立一個供寫入用的鎖定
F_UNLCK 刪除之前建立的鎖定
l_whence 也有三種方式:
SEEK_SET 以檔案開頭為鎖定的起始位置。
SEEK_CUR 以目前檔案讀寫位置為鎖定的起始位置
SEEK_END 以檔案結尾為鎖定的起始位置。
返回值 成功則返回0,若有錯誤則返回-1,錯誤原因存於errno.
flock(鎖定檔案或解除鎖定)
相關函式 open,fcntl
表頭檔案 #include<sys/file.h>
定義函式 int flock(int fd,int operation);
函式說明 flock()會依引數operation所指定的方式對引數fd所指的檔案做各種鎖定或解除鎖定的動作。此函式只能鎖定整個檔案,無法鎖定檔案的某一區域。
引數 operation有下列四種情況:
LOCK_SH 建立共享鎖定。多個程序可同時對同一個檔案作共享鎖定。
LOCK_EX 建立互斥鎖定。一個檔案同時只有一個互斥鎖定。
LOCK_UN 解除檔案鎖定狀態。
LOCK_NB 無法建立鎖定時,此操作可不被阻斷,馬上返回程序。通常與LOCK_SH或LOCK_EX 做OR(|)組合。
單一檔案無法同時建立共享鎖定和互斥鎖定,而當使用dup()或fork()時檔案描述詞不會繼承此種鎖定。
返回值 返回0表示成功,若有錯誤則返回-1,錯誤程式碼存於errno。
fsync(將緩衝區資料寫回磁碟)
相關函式 sync
表頭檔案 #include<unistd.h>
定義函式 int fsync(int fd);
函式說明 fsync()負責將引數fd所指的檔案資料,由系統緩衝區寫回磁碟,以確保資料同步。
返回值 成功則返回0,失敗返回-1,errno為錯誤程式碼。
lseek(移動檔案的讀寫位置)
相關函式 dup,open,fseek
表頭檔案 #include<sys/types.h>
#include<unistd.h>
定義函式 off_t lseek(int fildes,off_t offset ,int whence);
函式說明 每一個已開啟的檔案都有一個讀寫位置,當開啟檔案時通常其讀寫位置是指向檔案開頭,若是以附加的方式開啟檔案(如O_APPEND),則讀寫位置會指向檔案尾。當read()或write()時,讀寫位置會隨之增加,lseek()便是用來控制該檔案的讀寫位置。引數fildes 為已開啟的檔案描述詞,引數offset 為根據引數whence來移動讀寫位置的位移數。
引數 whence為下列其中一種:
SEEK_SET 引數offset即為新的讀寫位置。
SEEK_CUR 以目前的讀寫位置往後增加offset個位移量。
SEEK_END 將讀寫位置指向檔案尾後再增加offset個位移量。
當whence 值為SEEK_CUR 或SEEK_END時,引數offet允許負值的出現。
下列是教特別的使用方式:
1) 欲將讀寫位置移到檔案開頭時:lseek(int fildes,0,SEEK_SET);
2) 欲將讀寫位置移到檔案尾時:lseek(int fildes,0,SEEK_END);
3) 想要取得目前檔案位置時:lseek(int fildes,0,SEEK_CUR);
返回值 當呼叫成功時則返回目前的讀寫位置,也就是距離檔案開頭多少個位元組。若有錯誤則返回-1,errno 會存放錯誤程式碼。
附加說明 Linux系統不允許lseek()對tty裝置作用,此項動作會令lseek()返回ESPIPE。
範例 參考本函式說明
mkstemp(建立唯一的臨時檔案)
相關函式 mktemp
表頭檔案 #include<stdlib.h>
定義函式 int mkstemp(char * template);
函式說明 mkstemp()用來建立唯一的臨時檔案。引數template 所指的檔名稱字串中最後六個字元必須是XXXXXX。Mkstemp()會以可讀寫模式和0600 許可權來開啟該檔案,如果該檔案不存在則會建立該檔案。開啟該檔案後其檔案描述詞會返回。檔案順利開啟後返回可讀寫的檔案描述詞。若果檔案開啟失敗則返回NULL,並把錯誤程式碼存在errno 中。
錯誤程式碼 EINVAL 引數template 字串最後六個字元非XXXXXX。EEXIST 無法建立臨時檔案。
附加說明 引數template所指的檔名稱字串必須宣告為陣列,如:
char template[ ] =”template-XXXXXX”;
千萬不可以使用下列的表達方式
char *template = “template-XXXXXX”;
範例 #include<stdlib.h>
main( )
{
int fd;
char template[ ]=”template-XXXXXX”;
fd=mkstemp(template);
printf(“template = %s/n”,template);
close(fd);
}
執行 template = template-lgZcbo
open(開啟檔案)
相關函式 read,write,fcntl,close,link,stat,umask,unlink,fopen
表頭檔案 #include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
定義函式 int open( const char * pathname, int flags);
int open( const char * pathname,int flags, mode_t mode);
函式說明 引數pathname 指向欲開啟的檔案路徑字串。下列是引數flags 所能使用的旗標:
O_RDONLY 以只讀方式開啟檔案
O_WRONLY 以只寫方式開啟檔案
O_RDWR 以可讀寫方式開啟檔案。上述三種旗標是互斥的,也就是不可同時使用,但可與下列的旗標利用OR(|)運算子組合。
O_CREAT 若欲開啟的檔案不存在則自動建立該檔案。
O_EXCL 如果O_CREAT 也被設定,此指令會去檢查檔案是否存在。檔案若不存在則建立該檔案,否則將導致開啟檔案錯誤。此外,若O_CREAT與O_EXCL同時設定,並且欲開啟的檔案為符號連線,則會開啟檔案失敗。
O_NOCTTY 如果欲開啟的檔案為終端機裝置時,則不會將該終端機當成程序控制終端機。
O_TRUNC 若檔案存在並且以可寫的方式開啟時,此旗標會令檔案長度清為0,而原來存於該檔案的資料也會消失。
O_APPEND 當讀寫檔案時會從檔案尾開始移動,也就是所寫入的資料會以附加的方式加入到檔案後面。
O_NONBLOCK 以不可阻斷的方式開啟檔案,也就是無論有無資料讀取或等待,都會立即返回程序之中。
O_NDELAY 同O_NONBLOCK。
O_SYNC 以同步的方式開啟檔案。
O_NOFOLLOW 如果引數pathname 所指的檔案為一符號連線,則會令開啟檔案失敗。
O_DIRECTORY 如果引數pathname 所指的檔案並非為一目錄,則會令開啟檔案失敗。
此為Linux2.2以後特有的旗標,以避免一些系統安全問題。引數mode 則有下列數種組合,只有在建立新檔案時才會生效,此外真正建檔案時的許可權會受到umask值所影響,因此該檔案許可權應該為(mode-umaks)。
S_IRWXU00700 許可權,代表該檔案所有者具有可讀、可寫及可執行的許可權。
S_IRUSR 或S_IREAD,00400許可權,代表該檔案所有者具有可讀取的許可權。
S_IWUSR 或S_IWRITE,00200 許可權,代表該檔案所有者具有可寫入的許可權。
S_IXUSR 或S_IEXEC,00100 許可權,代表該檔案所有者具有可執行的許可權。
S_IRWXG 00070許可權,代表該檔案使用者組具有可讀、可寫及可執行的許可權。
S_IRGRP 00040 許可權,代表該檔案使用者組具有可讀的許可權。
S_IWGRP 00020許可權,代表該檔案使用者組具有可寫入的許可權。
S_IXGRP 00010 許可權,代表該檔案使用者組具有可執行的許可權。
S_IRWXO 00007許可權,代表其他使用者具有可讀、可寫及可執行的許可權。
S_IROTH 00004 許可權,代表其他使用者具有可讀的許可權
S_IWOTH 00002許可權,代表其他使用者具有可寫入的許可權。
S_IXOTH 00001 許可權,代表其他使用者具有可執行的許可權。
返回值 若所有欲核查的許可權都通過了檢查則返回0 值,表示成功,只要有一個許可權被禁止則返回-1。
錯誤程式碼 EEXIST 引數pathname 所指的檔案已存在,卻使用了O_CREAT和O_EXCL旗標。
EACCESS 引數pathname所指的檔案不符合所要求測試的許可權。
EROFS 欲測試寫入許可權的檔案存在於只讀檔案系統內。
EFAULT 引數pathname指標超出可存取記憶體空間。
EINVAL 引數mode 不正確。
ENAMETOOLONG 引數pathname太長。
ENOTDIR 引數pathname不是目錄。
ENOMEM 核心記憶體不足。
ELOOP 引數pathname有過多符號連線問題。
EIO I/O 存取錯誤。
附加說明 使用access()作使用者認證方面的判斷要特別小心,例如在access()後再作open()空檔案可能會造成系統安全上的問題。
範例 #include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
main()
{
int fd,size;
char s [ ]=”Linux Programmer!/n”,buffer[80];
fd=open(“/tmp/temp”,O_WRONLY|O_CREAT);
write(fd,s,sizeof(s));
close(fd);
fd=open(“/tmp/temp”,O_RDONLY);
size=read(fd,buffer,sizeof(buffer));
close(fd);
printf(“%s”,buffer);
}
執行 Linux Programmer!
read(由已開啟的檔案讀取資料)
相關函式 readdir,write,fcntl,close,lseek,readlink,fread
表頭檔案 #include<unistd.h>
定義函式 ssize_t read(int fd,void * buf ,size_t count);
函式說明 read()會把引數fd 所指的檔案傳送count個位元組到buf指標所指的記憶體中。若引數count為0,則read()不會有作用並返回0。返回值為實際讀取到的位元組數,如果返回0,表示已到達檔案尾或是無可讀取的資料,此外檔案讀寫位置會隨讀取到的位元組移動。
附加說明 如果順利read()會返回實際讀到的位元組數,最好能將返回值與引數count 作比較,若返回的位元組數比要求讀取的位元組數少,則有可能讀到了檔案尾、從管道(pipe)或終端機讀取,或者是read()被訊號中斷了讀取動作。當有錯誤發生時則返回-1,錯誤程式碼存入errno中,而檔案讀寫位置則無法預期。
錯誤程式碼 EINTR 此呼叫被訊號所中斷。
EAGAIN 當使用不可阻斷I/O 時(O_NONBLOCK),若無資料可讀取則返回此值。
EBADF 引數fd 非有效的檔案描述詞,或該檔案已關閉。
範例 參考open()。
sync(將緩衝區資料寫回磁碟)
相關函式 fsync
表頭檔案 #include<unistd.h>
定義函式 int sync(void)
函式說明 sync()負責將系統緩衝區資料寫回磁碟,以確保資料同步。
返回值 返回0。
write(將資料寫入已開啟的檔案內)
相關函式 open,read,fcntl,close,lseek,sync,fsync,fwrite
表頭檔案 #include<unistd.h>
定義函式 ssize_t write (int fd,const void * buf,size_t count);
函式說明 write()會把引數buf所指的記憶體寫入count個位元組到引數fd所指的檔案內。當然,檔案讀寫位置也會隨之移動。
返回值 如果順利write()會返回實際寫入的位元組數。當有錯誤發生時則返回-1,錯誤程式碼存入errno中。
錯誤程式碼 EINTR 此呼叫被訊號所中斷。
EAGAIN 當使用不可阻斷I/O 時(O_NONBLOCK),若無資料可讀取則返回此值。
EADF 引數fd非有效的檔案描述詞,或該檔案已關閉。