ANSIC標(biāo)準(zhǔn)采用“緩沖文件系統(tǒng)”處理的數(shù)據(jù)文件的,所謂緩沖文件系統(tǒng)是指系統(tǒng)自動(dòng)地在內(nèi)存中為程序中每一個(gè)正在使用的文件開(kāi)辟一塊“文件緩沖區(qū)”。
從內(nèi)存向磁盤輸出數(shù)據(jù)會(huì)先送到內(nèi)存中的緩沖區(qū),裝滿緩沖區(qū)后才一起送到磁盤上。
如果從磁盤向計(jì)算機(jī)讀入數(shù)據(jù),則從磁盤文件中讀取數(shù)據(jù)輸入到內(nèi)存緩沖區(qū)(充滿緩沖區(qū)),然后再?gòu)木彌_區(qū)逐個(gè)地將數(shù)據(jù)送到程序數(shù)據(jù)區(qū)(程序變量等)。緩沖區(qū)的大小根據(jù)C編譯系統(tǒng)決定的。
代碼示例:
#include <stdio.h>
#include <windows.h>
int main()
{
? ? FILE* pf = fopen("test.txt", "w");
? ? fputs("abcdef", pf);//先將代碼放在輸出緩沖區(qū)
? ? printf("睡眠10秒-已經(jīng)寫數(shù)據(jù)了,打開(kāi)test.txt文件,發(fā)現(xiàn)文件沒(méi)有內(nèi)容\n");
? ? Sleep(10000);
? ? printf("刷新緩沖區(qū)\n");
? ? fflush(pf);//刷新緩沖區(qū)時(shí),才將輸出緩沖區(qū)的數(shù)據(jù)寫到文件(磁盤)
? ? //注:fflush 在高版本的VS上不能使用了
? ? printf("再睡眠10秒-此時(shí),再次打開(kāi)test.txt文件,文件有內(nèi)容了\n");
? ? Sleep(10000);
? ? fclose(pf);
? ? //注:fclose在關(guān)閉文件的時(shí)候,也會(huì)刷新緩沖區(qū)
? ? pf = NULL;
? ? return 0;
}
在這里要著重了解fflush的作用;
在剛開(kāi)始運(yùn)行還未到10s時(shí),打開(kāi)文件其中沒(méi)有任何數(shù)據(jù):
文件指針(重點(diǎn))
緩沖文件系統(tǒng)中,關(guān)鍵的概念是“文件類型指針”,簡(jiǎn)稱“文件指針”。
每個(gè)被使用的文件都在內(nèi)存中開(kāi)辟了一個(gè)相應(yīng)的文件信息區(qū),用來(lái)存放文件的相關(guān)信息(如文件的名字,文件狀態(tài)及文件當(dāng)前的位置等)。
這些信息是保存在一個(gè)結(jié)構(gòu)體變量中的。該結(jié)構(gòu)體類型是有系統(tǒng)聲明的,取名FILE.
例如,VS2013編譯環(huán)境提供的 stdio.h 頭文件中有以下的文件類型申明:
struct _iobuf {
? ? ? ? char *_ptr;
? ? ? ? int ? _cnt;
? ? ? ? char *_base;
? ? ? ? int ? _flag;
? ? ? ? int ? _file;
? ? ? ? int ? _charbuf;
? ? ? ? int ? _bufsiz;
? ? ? ? char *_tmpfname;
? ? ? ?}; typedef struct _iobuf FILE;
不同的C編譯器的FILE類型包含的內(nèi)容不完全相同,但是大同小異。
每當(dāng)打開(kāi)一個(gè)文件的時(shí)候,系統(tǒng)會(huì)根據(jù)文件的情況自動(dòng)創(chuàng)建一個(gè)FILE結(jié)構(gòu)的變量,并填充其中的信息,使用者不必關(guān)
心細(xì)節(jié)。
一般都是通過(guò)一個(gè)FILE的指針來(lái)維護(hù)這個(gè)FILE結(jié)構(gòu)的變量,這樣使用起來(lái)更加方便。
下面我們可以創(chuàng)建一個(gè)FILE*的指針變量:
FILE* pf;//文件指針變量