open() 函式
原型
#include <fcntl.h>
#include <unistd.h>
int open(const char *pathname, int flags, mode_t mode);
-
pathname:要開啟的檔案的路徑。
-
flags:開啟檔案的模式(如只讀、只寫等)。常用的標誌包括:
- O_RDONLY:只讀模式。
- O_WRONLY:只寫模式。
- O_RDWR:讀寫模式。
- O_CREAT:如果檔案不存在,則建立新檔案。
- O_TRUNC:如果檔案已存在並且是以寫入模式開啟的,則截斷檔案為零長度。
- O_APPEND:將寫入操作附加到檔案末尾。
-
mode:檔案許可權,通常在建立檔案時使用。它是一個八進位制值(例如 0666),表示檔案的讀寫許可權(關於0666的解釋請看這篇部落格Linux中檔案的許可權)。
返回值
-
如果成功,返回一個非負整數(檔案描述符),可以用來進行後續的讀寫操作。
-
如果失敗,返回 -1,並且可以透過 errno(是一個全域性變數,定義在
<errno.h>
標頭檔案中,這篇部落格有涉及到) 獲取錯誤資訊。
錯誤處理
常見的錯誤包括:
-
EACCES:許可權被拒絕。
-
ENOENT:檔案不存在。
-
EEXIST:試圖建立一個已存在的檔案(當使用 O_CREAT 時)。
舉一個例子
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
int main() {
int fd = open("example.txt", O_RDWR, 0666);
if (fd == -1) {
perror("Error opening file");
close(fd);
return 1;
}
// 使用檔案描述符 fd 進行讀寫操作...
close(fd); // 關閉檔案
return 0;
}
輸出如下:
write()函式
原型
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
-
fd:要寫入的檔案描述符,通常是 open() 返回的值。
-
buf:指向要寫入的資料的指標。
-
count:要寫入的位元組數。
返回值
-
如果成功,返回實際寫入的位元組數。
-
如果失敗,返回 -1,並且可以透過 errno 獲取錯誤資訊。
錯誤處理
常見的錯誤包括:
-
EFAULT:buf 指標無效。
-
EBADF:檔案描述符無效。
-
EIO:I/O 錯誤。
舉一個例子
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
int main() {
int fd = open("example.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (fd == -1) {
perror("Error opening file");
close(fd);
return 1;
}
const char *data = "Hello, World!\n";
ssize_t bytes_written = write(fd, data, 14);
if (bytes_written == -1) {
perror("Error writing to file");
close(fd);
return 1;
}
printf("Wrote %zd bytes to file.\n", bytes_written);
close(fd); // 關閉檔案
return 0;
}
輸出如下:
close()函式
close() 函式用於關閉一個已開啟的檔案描述符。在 C/C++ 程式設計中,關閉檔案描述符是一個重要的步驟,以確保資源被正確釋放。
原型
#include <unistd.h>
int close(int fd);
- fd:要關閉的檔案描述符,通常是之前透過
open()
、socket()
、pipe()
等函式獲取的值。
返回值
-
如果成功,close() 返回 0。
-
如果失敗,返回 -1,並且可以透過 errno 獲取錯誤資訊。
工作原理
-
釋放資源:關閉檔案描述符後,作業系統會釋放與該檔案描述符相關的所有資源。這包括檔案的緩衝區、檔案鎖和其他相關資訊。
-
防止資源洩漏:如果不呼叫
close()
,程式在結束時可能會造成資源洩漏,因為作業系統可能會保留這些資源,直到程式終止。 -
同步資料:在某些情況下,關閉檔案描述符會導致緩衝區中的資料被強制寫入磁碟。對於寫入模式開啟的檔案,關閉操作可能會確保所有待寫入的資料都已被寫入。
錯誤處理
常見的錯誤包括:
-
EBADF:檔案描述符無效或未開啟。
-
EIO:發生 I/O 錯誤。
舉一個例子
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
int main() {
int fd = open("example.txt", O_WRONLY | O_CREAT, 0666);
if (fd == -1) {
perror("Error opening file");
return 1;
}
// 執行寫操作...
if (close(fd) == -1) {
perror("Error closing file");
return 1;
}
printf("File closed successfully.\n");
return 0;
}
輸出如下:
fopen()函式
fopen()
是 C 標準庫中的一個函式,用於開啟一個檔案並返回一個檔案指標,以便後續進行讀寫操作。它通常在 <stdio.h>
標頭檔案中宣告。
原型
FILE *fopen(const char *filename, const char *mode);
-
filename:要開啟的檔案的名稱(字串)。
-
mode:開啟檔案的模式,指示將如何訪問該檔案。常用的模式包括:
-
"r":只讀模式,檔案必須存在。
-
"w":只寫模式,若檔案存在則清空內容,不存在則建立新檔案。
-
"a":附加模式,資料會被寫入到檔案末尾。
-
"r+":讀寫模式,檔案必須存在。
-
"w+":讀寫模式,若檔案存在則清空內容,不存在則建立新檔案。
-
"a+":附加讀寫模式,可以讀檔案內容,寫入資料到檔案末尾。
-
返回值
-
返回一個指向 FILE 結構的指標,表示開啟的檔案。
-
如果開啟失敗,返回 NULL,並且可以透過 errno 獲取錯誤資訊。
舉一個例子
#include <stdio.h>
int main() {
FILE *file = fopen("example.txt", "r"); // 嘗試以只讀模式開啟檔案
if (file == NULL) {
perror("Error opening file"); // 列印錯誤資訊
fclose(file); // 關閉檔案
return 1;
}
// 進行檔案操作...
fclose(file); // 關閉檔案
return 0;
}
輸出如下:
重要注意事項
-
錯誤檢查:在使用
fopen()
後,始終檢查返回值,以確保檔案成功開啟。 -
關閉檔案:使用
fclose()
函式關閉開啟的檔案,以釋放系統資源。
fopen()和open()有什麼不同
fopen()
更適合一般的檔案處理需求,提供了較高的抽象層次,而 open()
則適合需要低階檔案控制的情況。
-
語言和庫
fopen()
:- 是 C 標準庫中的函式,通常用於 C 和 C++ 程式設計。 - 提供更高層次的檔案操作介面。
open()
:- 是 POSIX 系統呼叫,主要用於 C 語言(也可用於C++),適用於 UNIX/Linux 系統。 - 提供低階別的檔案操作。
-
返回值
fopen()
:-
返回一個指向 FILE 結構的指標,用於後續的檔案操作。
-
如果開啟失敗,返回 NULL。
open()
:-
返回一個檔案描述符(非負整數),用於標識開啟的檔案。
-
如果開啟失敗,返回 -1,並且可以透過 errno 檢查錯誤。
-
-
檔案模式
fopen()
:-
使用字串來指定開啟模式(如 "r"、"w"、"a" 等)。
-
提供更方便的讀寫功能。
open()
:-
使用整數標誌來指定開啟模式(如 O_RDONLY、O_WRONLY、O_RDWR 等)。
-
適合底層檔案操作,允許更多的細粒度控制。
-
-
錯誤處理
fopen()
:- 錯誤處理通常依賴於返回值(檢查指標是否為 NULL)。
open()
:- 需要檢查返回值並結合 errno 獲取具體錯誤資訊。
-
檔案操作
fopen()
:- 提供了
fread
、fwrite
、fprintf
、fscanf
等高階檔案操作函式,適合格式化輸入輸出。
open()
:- 主要與
read()
、write()
、lseek()
、close()
等系統呼叫一起使用,適合底層的檔案操作。
- 提供了