文件的输入和输出:流和缓冲区的概念和文件操作函数总结
流和緩沖區的概念理解
-
流(stream)
A stream is a source or destination of data that may be associated with a disk or other peripheral.
流(stream)是與磁盤或其它外圍設備關聯的數據的源或目的地。
Streams are a portable way of reading and writing data. They provide a flexible and efficient means of I/O. A Stream is a file or a physical device (e.g. printer or monitor) which is manipulated with a pointer to the stream.
流是(表達)讀寫數據的一種可移植的方法,它為一般的I/O操作提供了靈活有效的手段。一個流是一個由指針操作的文件或者是一個物理設備,而這個指針正是指向了這個流。
C語言中stdin、stdout、stderr分別是標準輸入流、標準輸出流及標準出錯流
-
緩沖區(buffer)
緩沖區存在于流與具體的設備終端或者存儲介質上的文件之間。
標準I / O提供緩存的目的是盡可能減少使用read和write調用的數量。
它也對每個I / O流自動地進行緩存管理。
標準I / O提供了三種類型的緩存:全緩存、行緩存、無緩存。
(1)全緩存。在這種情況下,當填滿標準I / O緩存后才進行實際I / O操作。對于駐在磁盤上的文件通常是由標準I / O庫實施全緩存的。在一個流上執行第一次I / O操作時,相關標準I / O函數通常調用malloc獲得需使用的緩存。
(2)行緩存。在這種情況下,當在輸入和輸出中遇到新行符時,標準I / O庫執行I / O操作。這允許我們一次輸出一個字符(用標準I/O fputc函數),但只有在寫了一行之后才進行實際I / O操作。
(3)不帶緩存。標準I / O庫不對字符進行緩存。如果用標準I / O函數寫若干字符到不帶緩存
的流中,則相當于用w r i t e系統調用函數將這些字符寫至相關聯的打開文件上。標準出錯流stderr通常是不帶緩存的,這就使得出錯信息可以盡快顯示出來,而不管它們是否含有一個新行字符。ANSI C要求下列緩存特征:
(1) 當且僅當標準輸入和標準輸出并不涉及交互作用設備時,它們才是全緩存的。
(2) 標準出錯決不會是全緩存的。涉及緩沖區的一些問題: gets是一個不推薦使用的函數。問題在于調用者在使用gets時不能指定緩存的長度。這樣就可能造成緩存越界(如若該行長于緩存長度),寫到緩存之后的存儲空間中,從而產生不可予料的后果。
刷新(flush)
緩存可由標準I / O例程自動地刷新(例如當填滿一個緩存時),或者可以調用函數ff l u s h刷新一個流。
在U N I X環境中,刷新有兩種意思:
-
在標準I / O庫方面,刷新意味著將緩存中的內容寫到磁盤上(該緩存可以只是局部填寫的)
-
在終端驅動程序方面(例如t c f l u s h函數),刷新表示丟棄已存在緩存中的數據。
-
FILE結構體的定義
在C語言中,通過打開流來關聯流及其目的地,使用的函數是fopen()
該函數返回一個指向文件的指針(FILE *),該指針包含了足夠的可以控制流準確地到達目的地的信息。
將它稱為流控制結構體
/* Definition of the control structure for streams */typedef struct {short level; /* fill/empty level of buffer */unsigned flags; /* File status flags */char fd; /* File descriptor */unsigned char hold; /* Ungetc char if no buffer */short bsize; /* Buffer size */unsigned char *buffer; /* Data transfer buffer */unsigned char *curp; /* Current active pointer */unsigned istemp; /* Temporary file indicator */short token; /* Used for validity checking */} FILE; /* This is the FILE object */mode參數指令
| r | 以只讀方式打開文件 |
| w | 打開或創建文本文件只寫,對已存在的文件清除原內容 |
| a | 追加。打開或創建文本文件,在尾部進行寫 |
| rb | 以只讀方式打開二進制文件 |
| wb | 打開或創建二進制文件只寫,對已存在的文件清除原內容 |
| ab | 追加。打開或創建二進制文件,在尾部進行寫 |
| r+ | 打開文本文件用于更新(讀和寫) |
| w+ | 打開或創建文本文件用于更新,對已存在的文件清除原內容 |
| a+ | 追加。打開或創建文本文件用于更新,在尾部進行寫 |
| r+b或rb+ | 打開二進制文件用于更新 |
| w+b或wb+ | 打開或創建二進制文件用于更新,對已存在的文件清除原內容 |
| a+b或ab+ | 追加,打開或創建二進制文件更新,在尾部進行寫 |
文件操作相關函數
fopen
FILE *fopen(const char *filename, const char *mode)
以mode指定模式打開filename指定的文件,并返回一個與之相關的流。操作失敗返回NULL
FILE *fp = fopen('1.txt','r'); //以只讀方式打開名為‘1.txt’的文本文件freopen
FILE *freopen(const char *filename, const char *mode, FILE *stream)
以mode指定模式打開filename指定文件,并將文件關聯到stream指定的流中,返回stream
fflush
int fflush(FILE *stream)
像它的名字一樣將緩沖區的全部尚未寫入文件的數據寫入到文件中。錯誤則返回EOF,否則返回0。
fflush(NULL); //清洗所有的輸出流fclose
int fclose(FILE *stream)
將所有未寫入的數據寫入stream中,丟棄緩沖區中的所有未讀輸入數據,并釋放自動分配的全部緩沖區,最后關閉流。錯誤則返回EOF,否則返回0。
remove
int remove(const char *filename)
刪除filename指定的文件,后續試圖打開該文件的操作將失敗。如果刪除失敗返回非0值。
rename
int rename(const char *oldname,const char* *newname)
修改文件的名字。操作失敗返回非0值。
tmpfile
FILE *tmpfile(void)
以模式‘wb+’創建一個臨時文件,當該文件被關閉或者程序正常結束時被自動刪除。如果創建成功函數返回一個流;如果創建失敗則返回NULL。
tmpnam
char tmpnam(char s[L_tmpname])
tmpnam(NULL)函數創建一個與現有文件名都不相同的字符串,并返回一個指向內部靜態數組的指針。
tmpnam(s)把創建的字符串保存到數組s中,并把它作為函數值返回;每次調用時生成不同的名字。
setvbuf
int setvbuf(FILE *stream, char *buf, int type, int size)
setvbuf的參數:一個指向流的指針,一個期望緩沖區的地址(buf),緩存的類型(type), 緩存區的字節大小(size)
-
type:
_IOFBF(滿緩沖):當緩沖區為空時,從流讀入數據。或者當緩沖區滿時,向流寫入數 據。_IOLBF(行緩沖):每次從流中讀入一行數據或向流中寫入一行數據。
_IONBF(無緩沖):直接從流中讀入數據或直接向流中寫入數據,而不設置緩沖區。
如果buf不是NULL,則setvbuf將buf所指向的區域作為緩沖區,否則將分配一個緩沖區。size決定緩沖區的長度。若出錯則返回非0值。
setbuf
如果buf的值為NULL,則關閉流stream的緩沖;否則setbuf函數等價于(void)setvbuf(stream,buf,_IOFBF,BUFSIZ);
總結
以上是生活随笔為你收集整理的文件的输入和输出:流和缓冲区的概念和文件操作函数总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue刷新当前路由:router-vie
- 下一篇: router锚点和html锚点,hash