C中的open(), write(), close(), fopen()

hisun9發表於2024-10-26

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;
}

輸出如下:

img

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;
}

輸出如下:

img

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;
}

輸出如下:

img

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;
}

輸出如下:

img

重要注意事項

  • 錯誤檢查:在使用 fopen() 後,始終檢查返回值,以確保檔案成功開啟。

  • 關閉檔案:使用 fclose() 函式關閉開啟的檔案,以釋放系統資源。

fopen()和open()有什麼不同

fopen() 更適合一般的檔案處理需求,提供了較高的抽象層次,而 open() 則適合需要低階檔案控制的情況。

  1. 語言和庫

    fopen()

     - 是 C 標準庫中的函式,通常用於 C 和 C++ 程式設計。
    
     - 提供更高層次的檔案操作介面。
    

    open()

     - 是 POSIX 系統呼叫,主要用於 C 語言(也可用於C++),適用於 UNIX/Linux 系統。
    
     - 提供低階別的檔案操作。
    
  2. 返回值

    fopen()

    • 返回一個指向 FILE 結構的指標,用於後續的檔案操作。

    • 如果開啟失敗,返回 NULL。

    open()

    • 返回一個檔案描述符(非負整數),用於標識開啟的檔案。

    • 如果開啟失敗,返回 -1,並且可以透過 errno 檢查錯誤。

  3. 檔案模式

    fopen()

    • 使用字串來指定開啟模式(如 "r"、"w"、"a" 等)。

    • 提供更方便的讀寫功能。

    open()

    • 使用整數標誌來指定開啟模式(如 O_RDONLY、O_WRONLY、O_RDWR 等)。

    • 適合底層檔案操作,允許更多的細粒度控制。

  4. 錯誤處理

    fopen()

    • 錯誤處理通常依賴於返回值(檢查指標是否為 NULL)。

    open()

    • 需要檢查返回值並結合 errno 獲取具體錯誤資訊。
  5. 檔案操作

    fopen()

    • 提供了 freadfwritefprintffscanf 等高階檔案操作函式,適合格式化輸入輸出。

    open()

    • 主要與 read()write()lseek()close() 等系統呼叫一起使用,適合底層的檔案操作。

相關文章