一、open函數的使用
在linux系統中,open函數可以打開或創建一個文件。函數原型如下:
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>
1 int open(const char *pathname, int flags);
2 int open(const char *pathname, int flags, mode_t mode);
3 返回值:成功返回新分配的文件描述符,出錯返回-1並設置errno
pathname參數是要打開或創建的文件名,和fopen一樣,pathname既可以是相對路徑也可以是絕對路徑。flags參數有一系列常數值可供選擇,可以同時選擇多個常數用按位或運算符連接起來,所以這些常數的宏定義都以O_開頭,表示or。
必選項:以下三個常數中必須指定一個,且僅允許指定一個。
1 O_RDONLY 只讀打開 2 O_WRONLY 只寫打開 3 O_RDWR 可讀可寫打開
以下可選項可以同時指定0個或多個,和必選項按位或起來作為flags參數。可選項有很多,這里只介紹一部分,其它選項可參考open(2)的Man Page:
1 O_APPEND 表示追加。如果文件已有內容,這次打開文件所寫的數據附加到文件的末尾而不覆蓋原來的內容。 2 O_CREAT 若此文件不存在則創建它。使用此選項時需要提供第三個參數mode,表示該文件的訪問權限。 3 O_EXCL 如果同時指定了O_CREAT,並且文件已存在,則出錯返回。 4 O_TRUNC 如果文件已存在,並且以只寫或可讀可寫方式打開,則將其長度截斷(Trun-cate)為0字節。 5 O_NONBLOCK 對於設備文件,以O_NONBLOCK方式打開可以做非阻塞I/O(Nonblock I/O)。
注意open函數與C標准I/O庫的fopen函數有些細微的區別:
以可寫的方式fopen一個文件時,如果文件不存在會自動創建,而open一個文件時必須明確指定O_CREAT才會創建文件,否則文件不存在就出錯返回。
以w或w+方式fopen一個文件時,如果文件已存在就截斷為0字節,而open一個文件時必須明確指定O_TRUNC才會截斷文件,否則直接在原來的數據上改寫。
第三個參數mode指定文件權限,可以用八進制數表示,比如0644表示-rw-r-r–,也可以用S_IRUSR、S_IWUSR等宏定義按位或起來表示,詳見open(2)的Man Page。要注意的是,文件權限由open的mode參數和當前進程的umask掩碼共同決定。
二、close函數
close函數用於關閉一個已打開的文件,函數原型如下:
1 int close(int fd); 2 返回值:成功返回0,出錯返回-1並設置errno
參數fd是要關閉的文件描述符。需要說明的是,當一個進程終止時,內核對該進程所有尚未關閉的文件描述符調用close關閉,所以即使用戶程序不調用close,在終止時內核也會自動關閉它打開的所有文件。但是對於一個長年累月運行的程序(比如網絡服務器),打開的文件描述符一定要記得關閉,否則隨着打開的文件越來越多,會占用大量文件描述符和系統資源。
由open返回的文件描述符一定是該進程尚未使用的最小描述符。由於程序啟動時自動打開文件描述符0、1、2,因此第一次調用open打開文件通常會返回描述符3,再調用open就會返回4。可以利用這一點在標准輸入、標准輸出或標准錯誤輸出上打開一個新文件,實現重定向的功能。例如,首先調用close關閉文件描述符1,然后調用open打開一個常規文件,則一定會返回文件描述符1,這時候標准輸出就不再是終端,而是一個常規文件了,再調用printf就不會打印到屏幕上,而是寫到這個文件中了。
【實例】
1 int main(int argc,char *argv[]) 2 { 3 int fd; 4 5 if(argc < 2) 6 { 7 printf("./app filename\n"); 8 exit(1); 9 } 10 umask(0);//設置權限之前要將默認權限關閉 11 //創建一個文件,以可讀可寫方式打開,文件的權限為777 12 fd = open(argv[1],O_CREAT | O_RDWR,0777); 13 printf("%d\n",fd); 14 close(fd); 15 16 return 0; 17 }