open函數的使用
調用open函數可以打開或創建一個文件
#include <sys/stat.h> #include <fcntl.h> #include <sys/types.h>
int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode);
- pathname參數是要打開或創建的文件名,和fopen一樣,pathname既可以是相對路徑也可以是絕對路徑.
- flags參數用來說明此函數的多個選項。用下列一個或多個常量進行”或”運算構成flags參數。(常量在fcntl.h頭文件中定義)
以下三個常數中必須指定一個,且僅允許指定一個。
- O_RDONLY 只讀打開
- O_WRONLY 只寫打開
- O_RDWR 可讀可寫打開
以下可選項可以同時指定0個或多個,和必選項按位或起來作為flags參數。可選項有很多,這里只介紹一部分,其它選項可參考open(2)的Man Page:
- O_APPEND 表示追加。如果文件已有內容,這次打開文件所寫的數據附加到文件的末尾而不覆蓋原來的內容。
- O_CREAT 若此文件不存在則創建它。使用此選項時需要提供第三個參數mode,表示該文件的訪問權限。
- O_EXCL 如果同時指定了O_CREAT,並且文件已存在,則出錯返回。
- O_TRUNC 如果文件已存在,並且以只寫或可讀可寫方式打開,則將其長度截斷(Trun-cate)為0字節。
- O_NONBLOCK 對於設備文件,以O_NONBLOCK方式打開可以做非阻塞I/O(Nonblock I/
O) -
mode參數:
指定文件權限,4位數字,第一位一般是0 后面三位是 r w x 4 2 1 一般用八進制表示
注意,由open函數返回的文件描述符一定是最小的未用描述符數值。一個進程默認打開3個文件描述符,
STDIN_FILENO 0 STDOUT_FILENO 1 STDERR_FILENO 2
注意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)的ManPage。要注意的是,文件權限由open的mode參數和當前進程的umask掩碼共同決定。
#include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> int main(void) { int fd; fd = open("hello", O_CREAT | O_RDWR, 0777); if (fd < 0) { perror("open"); exit(-1); } printf("fd = %d\n", fd); return 0; }
close函數的使用
close函數關閉一個已打開的文件:
#include <unistd.h> int close(int fd);
返回值:成功返回0,出錯返回-1並設置errno
參數fd是要關閉的文件描述符。需要說明的是,當一個進程終止時,內核對該進程所有尚未關閉的文件描述符調用close關閉,所以即使用戶程序不調用close,在終止時內核也會自動關閉它打開的所有文件。但是對於一個長年累月運行的程序(比如網絡服務器),打開的文件描述符一定要記得關閉,否則隨着打開的文件越來越多,會占用大量文件描述符和系統資源。
由open返回的文件描述符一定是該進程尚未使用的最小描述符。由於程序啟動時自動打開文件描述符0、1、2,因此第一次調用open打開文件通常會返回描述符3,再調用open就會返回4。可以利用這一點在標准輸入、標准輸出或標准錯誤輸出上打開一個新文件,實現重定向的功能。例如,首先調用close關閉文件描述符1,然后調用open打開一個常規文件,則一定會返回文件描述符1,這時候標准輸出就不再是終端,而是一個常規文件了,再調用printf就不會打印到屏幕上,而是寫到這個文件中了。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> int main(void) { int fd; close(STDOUT_FILENO); fd = open("cat", O_CREAT | O_RDWR, 0664); if (fd < 0) { perror("open"); exit(-1); } printf("hello world\n"); return 0; }