跳轉到內容

C 程式設計/stdio.h/fopen

來自華夏公益教科書,開放的書籍,開放的世界

fopen,在 glibc 和 musl 中實現,將使用 open 系統呼叫。

使用 fopen 開啟檔案

[編輯 | 編輯原始碼]

使用 fopen 開啟檔案,它返回一個與指定檔案或其他裝置關聯的 I/O 流,可以從中進行讀寫。如果函式失敗,它將返回一個空指標。

相關的 C 庫函式 freopen 在首先關閉與其引數關聯的任何開啟流後執行相同的操作。

它們被定義為

FILE *fopen(const char *path, const char *mode);
FILE *freopen(const char *path, const char *mode, FILE *fp);

fopen 函式本質上是 Unix 作業系統 open 系統呼叫的稍微高階一點的包裝器。同樣,fclose 通常是 Unix 系統呼叫 close 的一個薄包裝器,而 C FILE 結構本身通常對應於一個 Unix 檔案描述符。在 POSIX 環境中,fdopen 函式可用於從檔案描述符初始化 FILE 結構;但是,檔案描述符是一個純粹的 Unix 概念,在標準 C 中不存在。

fopenfreopenmode 引數必須是一個以以下序列之一開頭的字串

模式 描述 開始..
r rb 以讀模式開啟(檔案必須存在) 開頭
w wb 以寫模式開啟(如果檔案不存在則建立檔案)。刪除內容並覆蓋檔案。 開頭
a ab 以追加模式開啟(如果檔案不存在則建立檔案) 結尾
r+ rb+ r+b 以讀寫模式開啟(檔案必須存在) 開頭
w+ wb+ w+b 以讀寫模式開啟。如果檔案存在,則刪除內容並覆蓋檔案,否則建立一個空的新的檔案 開頭
a+ ab+ a+b 以讀寫模式開啟(如果檔案存在則追加) 結尾

b” 代表二進位制。C 標準提供了兩種型別的檔案——文字檔案和二進位制檔案——儘管作業系統不需要區分兩者。文字檔案 是一個由文字組成的檔案,這些文字按行排列,並帶有某種區分行尾的字元或序列(在 Unix 中,一個裸行進字元;在 Microsoft Windows 中,一個回車符後跟一個換行符)。當從文字檔案讀取位元組時,行尾序列通常對映到換行符以方便處理。當寫入文字檔案時,在寫入之前,一個裸換行符被對映到 OS 特定的行尾字元序列。二進位制檔案 是一個檔案,其中位元組以“原始”方式讀入,並以“原始”方式傳送,沒有任何對映。

當以更新模式開啟檔案時('+' 作為模式引數中的第二個或第三個字元),可以在關聯的流上執行輸入和輸出。但是,寫操作不能在沒有對 fflush 或檔案定位函式(fseekfsetposrewind)的中間呼叫情況下緊隨讀操作之後,讀操作也不能在沒有對檔案定位函式的中間呼叫情況下緊隨寫操作之後。[1]

寫入和追加模式將嘗試建立給定名稱的檔案,如果還沒有這樣的檔案。如上所述,如果此操作失敗,fopen 將返回 NULL

Glibc/musl 注意事項

[編輯 | 編輯原始碼]

Musl 和 Glibc 在 Linux 上支援e模式,它在新的檔案描述符上設定O_CLOEXECO_CLOEXEC是 Linux 2.6 的功能,在 Linux 手冊頁專案 中有記錄

為新的檔案描述符啟用 close-on-exec 標誌。指定此標誌允許程式避免額外的 fcntl(2) F_SETFD 操作來設定 FD_CLOEXEC 標誌。此外,在某些多執行緒程式中使用此標誌至關重要,因為使用單獨的 fcntl(2) F_SETFD 操作來設定 FD_CLOEXEC 標誌不足以避免一個執行緒開啟檔案描述符時另一個執行緒執行 fork(2) 加 execve(2) 時的競爭條件。

參見 http://danwalsh.livejournal.com/53603.html

參見 musl cgit 以瞭解 Musl 的實現。

參考資料

[編輯 | 編輯原始碼]
華夏公益教科書