下列三個函數打開一個標準I/O流。
#include <stdio.h>FILE *fopen( const char *restrict pathname, const char *restrict type );FILE *freopen( const char *restrict pathname, const char *restrict type, FILE *restrict fp );FILE *fdopen( int filedes, const char *type );三個函數的返回值:若成功則返回文件指針,若出錯則返回NULL
這三個函數的區別是:
(1)fopen打開一個指定的文件。
(2)freopen在一個指定的流上打開一個指定的文件,如若該流已經打開,則先關閉該流。若該流已經定向,則freopen清除該定向。此函數一般用于將一個指定的文件打開為一個預定義的流:標準輸入、標準輸出或標準出錯。
(3)fdopen獲取一個現有的文件描述符(我們可能從open、dup、dup2、fcntl、pipe、socket、socketpair或accept函數得到此文件描述符),并使一個標準的I/O流與該描述符相結合。此函數常用于由創建管道和網絡通信通道函數返回的描述符。因為這些特殊類型的文件不能用標準I/O fopen函數打開,所以我們必須先調用設備專用函數以獲得一個文件描述符,然后用fdopen使一個標準I/O流與該描述符相關聯。
type參數指定對該I/O流的讀、寫方式,ISO C規定type參數可以有15種不同的值,見表5-2。
使用字符b作為type的一部分,這使得標準I/O系統可以區分文本文件和二進制文件。因為UNIX內核并不對這兩種文件進行區分,所以在UNIX系統環境下指定字符b作為type的一部分實際上并無作用。
對于fdopen,type參數的意義稍有區別。因為該描述符已被打開,所以fdopen為寫而打開并不截短該文件。另外,標準I/O添寫方式也不能用于創建該文件(因為如若一個描述符引用一個文件,則該文件一定已經存在)。
當用添寫方式打開一文件后,則每次寫都將數據寫到文件的當前尾端處。如若有多個進程用標準I/O添寫方式打開了同一文件,那么來自每個進程的數據都將正確地寫到文件中。
當以讀和寫類型打開一文件時(type中+符號),具有下列限制:
如果中間沒有fflush、fseek、fsetpos或rewind,則在輸出的后面不能直接跟隨輸入。
如果中間沒有fseek、fsetpos或rewind,或者一個輸入操作沒有到達文件尾端,則在輸入操作之后不能直接跟隨輸出。
對應于表5-2,我們在表5-3中列出了打開一個流的6種不同的方式。
表5-3 打開一個標準I/O流的6種不同的方式
限制 | r | w | a | r+ | w+ | a+ |
文件必須已存在 | @ | @ | ||||
擦除文件以前的內容 | @ | @ | ||||
流可以讀 | @ | @ | @ | @ | ||
流可以寫 | @ | @ | @ | @ | @ | |
流只可在尾端寫 | @ | @ |
注意,在指定w或a類型創建一個新文件時,我們無法說明該文件的訪問權限位。
除非流引用終端設備,否則按系統默認的情況,流被打開時是全緩沖的。若流引用終端設備,則該流是行緩沖的。一旦打開了流,那么在對該流執行任何操作之前,如果希望,則可使用setbuf和setvbuf改變緩沖的類型。
調用fclose關閉一個打開的流。
#include <stdio.h>int fclose( FILE *fp );返回值:若成功則返回0,若出錯則返回EOF
在該文件被關閉之前,沖洗緩沖區中的輸出數據。丟棄緩沖區中的任何輸入數據。如果標準I/O庫已經為該流自動分配了一個緩沖區,則釋放此緩沖區。
當一個進程正常終止時(直接調用exit函數,或從main函數返回),則所有帶未寫緩沖數據的標準I/O都會被沖洗,所有打開的標準I/O流都會被關閉。
本篇博文內容摘自《UNIX環境高級編程》(第二版),僅作個人學習記錄所用。關于本書可參考:http://www.apuebook.com/。
新聞熱點
疑難解答