網(wǎng)站備案 哪個(gè)省最松發(fā)外鏈的平臺(tái)有哪些
C語(yǔ)言文件操作(1)
文章目錄
- C語(yǔ)言文件操作(1)
- 一、理解文件
- 1.概述
- 2.分類
- ①.正常角度
- ②.文本文件和二進(jìn)制文件
- 二、文件的打開(kāi)和關(guān)閉
- 1.流和標(biāo)準(zhǔn)流
- 2.文件類型指針
- 3.文件的打開(kāi)和關(guān)閉以及使用類型
- 三、文件緩沖區(qū)
一、理解文件
1.概述
首先,我們要知道文件都是存儲(chǔ)在磁盤上的,而我們平時(shí)寫在編譯器上寫的代碼等在保存之前都是存儲(chǔ)在內(nèi)存中的,也即帶電存儲(chǔ),計(jì)算機(jī)內(nèi)存是一種臨時(shí)存儲(chǔ)器,它的內(nèi)容在計(jì)算機(jī)關(guān)閉或重啟時(shí)會(huì)被清除,或者程序退出,內(nèi)存回收,數(shù)據(jù)就丟失了。
如果想要永久化的保存數(shù)據(jù),我們可以使用存儲(chǔ)在磁盤上的文件。
2.分類
①.正常角度
從程序設(shè)計(jì)的角度來(lái)看,文件主要分為程序文件和數(shù)據(jù)文件。程序文件也就是我們常說(shuō)的.c .obj .exe文件。
而在編程過(guò)程中的文件操作主要操作的就是數(shù)據(jù)文件,程序運(yùn)行時(shí)讀取數(shù)據(jù)的文件和程序運(yùn)行時(shí)輸出內(nèi)容的文件。
注意:
程序中的數(shù)據(jù) ———> 磁盤中的文件,這叫輸出,即寫
程序中的數(shù)據(jù) <——— 磁盤中的文件,這叫輸入,即讀
輸出輸入是相對(duì)于程序中的數(shù)據(jù)來(lái)說(shuō)的。
②.文本文件和二進(jìn)制文件
根據(jù)數(shù)據(jù)的存儲(chǔ)形式,數(shù)據(jù)文件被稱為文本文件或者二進(jìn)制文件。
數(shù)據(jù)在內(nèi)存中以?進(jìn)制的形式存儲(chǔ),如果不加轉(zhuǎn)換的輸出到外存,就是二進(jìn)制文件。
如果要求在外存上以ASCII碼的形式存儲(chǔ),則需要在存儲(chǔ)前轉(zhuǎn)換。以ASCII字符的形式存儲(chǔ)的文件就是文本文件。
在內(nèi)存中,字符?律以ASCII形式存儲(chǔ),數(shù)值型數(shù)據(jù)既可以用ASCII形式存儲(chǔ),也可以使用?進(jìn)制形式存儲(chǔ)。
舉個(gè)例子:
將100以二進(jìn)制形式寫到文件里,出現(xiàn)不認(rèn)識(shí)的函數(shù)大家不用擔(dān)心,后續(xù)都會(huì)提到的呀!
#include <errno.h>
int main()
{int a = 100;FILE* fp = fopen("test.txt", "wb");if (fp == NULL){perror("fopen");return 1;}fwrite(&a, 4, 1, fp);fclose(fp);fp = NULL;return 0;
}
那讓我們一起來(lái)驗(yàn)證一下:
1.將這個(gè)文件拖到源文件下面
2.右鍵點(diǎn)擊打開(kāi)方式選項(xiàng)
3.選擇二進(jìn)制編輯器
二、文件的打開(kāi)和關(guān)閉
1.流和標(biāo)準(zhǔn)流
我們程序的數(shù)據(jù)需要輸出到各種外部設(shè)備,也需要從外部設(shè)備獲取數(shù)據(jù),不同的外部設(shè)備的輸入輸出操作各不相同,為了方便程序員對(duì)各種設(shè)備進(jìn)行方便的操作,我們抽象出了流的概念,我們可以把流想象成流淌著字符的河。
C程序針對(duì)文件、畫面、鍵盤等的數(shù)據(jù)輸入輸出操作都是同流操作的。一般情況下,我們要想向流里寫數(shù)據(jù),或者從流中讀取數(shù)據(jù),都是要打開(kāi)流,然后操作。
那為什么我們從鍵盤輸入數(shù)據(jù),向屏幕上輸出數(shù)據(jù),并沒(méi)有打開(kāi)流呢?
那是因?yàn)镃語(yǔ)言程序在啟動(dòng)的時(shí)候,默認(rèn)打開(kāi)了3個(gè)流:
stdin - 標(biāo)準(zhǔn)輸入流,在大多數(shù)的環(huán)境中從鍵盤輸入。
stdout - 標(biāo)準(zhǔn)輸出流,在大多數(shù)的環(huán)境中輸出至顯示器界面。
stderr - 標(biāo)準(zhǔn)錯(cuò)誤流,在大多數(shù)環(huán)境中輸出到顯示器界面。
這是默認(rèn)打開(kāi)了這三個(gè)流,我們使scanf、printf等函數(shù)就可以直接進(jìn)行輸入輸出操作的。
2.文件類型指針
在使用文件,打開(kāi)文件時(shí),文件都會(huì)在內(nèi)存中創(chuàng)建一個(gè)“文件信息區(qū)”,存放文件的相關(guān)信息,這些信息都保存在一個(gè)結(jié)構(gòu)體變量里,FILE是這個(gè)結(jié)構(gòu)體類型,創(chuàng)建一個(gè)FILE*類型的指針,可以指向這個(gè)文件信息區(qū),并且通過(guò)文件信息來(lái)訪問(wèn)這個(gè)文件,通過(guò)文件指針變量能夠間接找到這個(gè)與他關(guān)聯(lián)的文件。
stdin、stdout、stderr三個(gè)流的類型是: FILE* ,通常稱為文件指針。C語(yǔ)言中,就是通過(guò) FILE* 的文件指針來(lái)維護(hù)流的各種操作的。
3.文件的打開(kāi)和關(guān)閉以及使用類型
文件的打開(kāi)和關(guān)閉,是依賴與fopen函數(shù)和fclose函數(shù)
//文件的打開(kāi)
FILE* fp = fopen("test.txt", "wb");//注意:文件名和打開(kāi)模式都是兩個(gè)雙引號(hào)if (fp == NULL){perror("fopen");return 1;}
//文件的關(guān)閉fclose(fp);fp = NULL;
fopen打開(kāi)成功返回文件信息區(qū)的地址,打開(kāi)失敗返回NULL。
FILE * fopen ( const char * filename, const char * mode );
下面讓我們一起來(lái)看看mode,也就是文件的打開(kāi)模式
首先,我們來(lái)看一下"r"和"w"
r:文件必須存在,不存在的話則打開(kāi)失敗
w:如果文件存在會(huì)清空原來(lái)內(nèi)容,相當(dāng)于變成空文件,如果不存在,則創(chuàng)建一個(gè)新的文件。
更多有關(guān)mode的類型,可以點(diǎn)開(kāi)這個(gè)鏈接。
fopen的mode
三、文件緩沖區(qū)
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)決定的。
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.tx文件,文件有內(nèi)容了\n");Sleep(10000);//避免是fclose的影響fclose(pf);//注:fclose在關(guān)閉文件的時(shí)候,也會(huì)刷新緩沖區(qū)pf = NULL;return 0;
}
因?yàn)橛芯彌_區(qū)的存在,C語(yǔ)言在操作文件的時(shí)候,需要做刷新緩沖區(qū)或者在文件操作結(jié)束的時(shí)候關(guān)閉文件。