C語(yǔ)言采用文本方式和二進(jìn)制方式打開(kāi)文件的區(qū)別分析
稍微了解C程序設(shè)計(jì)的人都知道,文本文件和二進(jìn)制文件在計(jì)算機(jī)上面都是以0,1存儲(chǔ)的,那么兩者怎么還存在差別呢?對(duì)于編程人員來(lái)說(shuō),文本文件和二進(jìn)制文件就是一個(gè)聲明,指明了你應(yīng)該以什么方式(文本方式/二進(jìn)制)打開(kāi)這個(gè)文件,用什么函數(shù)讀寫(xiě)這個(gè)文件(讀寫(xiě)函數(shù)),怎么判斷讀到這個(gè)文件結(jié)尾等。
具體分析如下:
一、以哪種方式打開(kāi)一個(gè)文件:
ANSI C規(guī)定了標(biāo)準(zhǔn)輸入輸出函數(shù)庫(kù),用 fopen()函數(shù)打開(kāi)文件。fopen()函數(shù)的調(diào)用方式一般為:
FILE *fp;
fp=fopen(文件名,使用文件方式);
使用文件方式見(jiàn)下表:
使用文件方式 | 含義 |
"r"(只讀) | 為輸入打開(kāi)一個(gè)文本文件 |
"w"(只寫(xiě)) | 為輸出打開(kāi)一個(gè)文本文件 |
"a"(追加) | 為追加打開(kāi)一個(gè)文本文件 |
"rb"(只讀) | 為輸入打開(kāi)一個(gè)二進(jìn)制文件 |
"wb"(只寫(xiě)) | 為輸出打開(kāi)一個(gè)二進(jìn)制文件 |
"ab"(追加) | 為追加打開(kāi)一個(gè)二進(jìn)制文件 |
"r+"(讀寫(xiě)) | 為讀/寫(xiě)打開(kāi)一個(gè)文本文件 |
"w+"(讀寫(xiě)) | 為讀/寫(xiě)創(chuàng)建一個(gè)文本文件 |
"a+"(讀寫(xiě)) | 為讀/寫(xiě)打開(kāi)一個(gè)文本文件 |
"rb+"(讀寫(xiě)) | 為讀/寫(xiě)打開(kāi)一個(gè)二進(jìn)制文件 |
"wb+"(讀寫(xiě)) | 為讀/寫(xiě)創(chuàng)建一個(gè)二進(jìn)制文件 |
"ab+"(讀寫(xiě)) | 為讀/寫(xiě)打開(kāi)一個(gè)二進(jìn)制文件 |
同一個(gè)文件從磁盤(pán)讀取文件到內(nèi)存(程序數(shù)據(jù)區(qū)或者緩存區(qū))時(shí),兩種方式下,內(nèi)存中的內(nèi)容一般不相同,這就是兩種打開(kāi)方式的實(shí)質(zhì)性差別。
這里要說(shuō)一個(gè)背景,那就是在windows下,它會(huì)做一個(gè)處理,就是寫(xiě)文件時(shí),換行符會(huì)被轉(zhuǎn)換成回車,換行符存在磁盤(pán)文件上,而讀磁盤(pán)上的文件時(shí),它又會(huì)進(jìn)行逆處理,就是把文件中連續(xù)的回車,換行符轉(zhuǎn)換成換行符。
因此,在讀取一個(gè)磁盤(pán)文件時(shí),文本方式讀取到文件內(nèi)容很有可能會(huì)比二進(jìn)制文件短,因?yàn)槲谋痉绞阶x取要把回車,換行兩個(gè)字符變成一個(gè)字符,相當(dāng)于截短了文件。但是為什么僅僅是可能呢?因?yàn)榭赡芪谋局胁淮嬖谶B著的45,42這兩個(gè)字節(jié)(45是CR回車的ASCII碼,42是換行符CL的ASCII碼),也就不存在“截短”操作了,因此讀到的內(nèi)容是一樣的。
具體的來(lái)說(shuō),文件文件(以文本方式寫(xiě)的),最好以文本方式讀。二進(jìn)制文件(以二進(jìn)制方式寫(xiě)的),最好以二進(jìn)制方式讀。不然可能會(huì)不正確。
二、以什么函數(shù)讀寫(xiě)文件
數(shù)據(jù)怎么在磁盤(pán)上寫(xiě)不是由文件打開(kāi)方式?jīng)Q定的,而是由寫(xiě)函數(shù)決定的。數(shù)據(jù)怎么從磁盤(pán)上讀也不是由文件打開(kāi)方式?jīng)Q定的,而是由讀函數(shù)決定的。
上面說(shuō)的數(shù)據(jù)怎么寫(xiě)是指,一種類型的變量是怎么存的?比如int 12,可以直接存12的二進(jìn)制碼(4個(gè)字節(jié)),也可以存字符1,字符2.
數(shù)據(jù)怎么讀的是指,我要讀一個(gè)int變量,是直接讀sizeof(int)個(gè)字節(jié),還是一個(gè)字符一個(gè)字符的讀,直到讀到的字符不是數(shù)字字符。
C里面有兩組文件讀寫(xiě)函數(shù)恰好支持上面兩種方式的讀寫(xiě):
1.fread(buffer,size,count,fp),fwrite(buffer,size,count,fp)。用來(lái)讀寫(xiě)一個(gè)數(shù)據(jù)塊。它對(duì)應(yīng)的是第一種存儲(chǔ)方式。直接按類型的字節(jié)長(zhǎng)度指定讀寫(xiě)的字節(jié)數(shù)。
2.fprintf函數(shù)和fscanf函數(shù).它對(duì)應(yīng)的是第二種讀寫(xiě)方式。即以字符的方式讀寫(xiě)。(fprintf函數(shù)、fscanf函數(shù)與printf函數(shù)、scanf函數(shù)的作用相仿,都是格式化讀寫(xiě)函數(shù)。fprintf和fscanf函數(shù)的讀寫(xiě)對(duì)象是磁盤(pán)文件,而printf和scanf函數(shù)的讀寫(xiě)對(duì)象是終端。)
它們的一般調(diào)用格式為:
fprintf(文件指針,格式字符串,輸出列表); fscanf (文件指針,格式字符串,輸入列表);
三、怎么判斷文件尾
在C語(yǔ)言,或更精確地說(shuō)成 C標(biāo)準(zhǔn)函式庫(kù)中,有一個(gè)特別的字符EOF(stdio.h中這個(gè)定義 #define EOF (-1) ),它表示:文件結(jié)束符(end of file)。在while循環(huán)中以EOF作為文件結(jié)束標(biāo)志,這種以EOF作為文件結(jié)束標(biāo)志的文件,必須是文本文件。在文本文件中,數(shù)據(jù)都是以字符的ASCII代碼值的形式存放。我們知道,ASCII代碼值的范圍是0~255,不可能出現(xiàn)-1,因此可以用EOF作為文件結(jié)束標(biāo)志。
但是,C語(yǔ)言中,當(dāng)把數(shù)據(jù)以二進(jìn)制形式存放到文件中時(shí),就會(huì)有-1值的出現(xiàn),此時(shí)不能采用EOF作為二進(jìn)制文件的結(jié)束標(biāo)志。為解決這個(gè)問(wèn)題,ANSI C提供一個(gè)feof函數(shù),用來(lái)判斷文件是否結(jié)束。如果遇到文件結(jié)束,函數(shù)feof(fp)的值為1,否則為0.
feof函數(shù)既可用以判斷二進(jìn)制文件是否結(jié)束,也可以用以判斷文本文件是否結(jié)束。但是要注意feof用以判斷文本文件尾時(shí),如果代碼編寫(xiě)不當(dāng),可能會(huì)把文本文中中的文件結(jié)束符EOF也讀取出來(lái)了;具體可以參考http://baike.baidu.com/view/656648.htm中feof函數(shù)的用法。
四、知道一個(gè)文件是文本文件,還是二進(jìn)制文件,更多的“提醒”我們,應(yīng)該選擇哪種讀寫(xiě)函數(shù)。
正如前文所說(shuō)的,數(shù)據(jù)怎么存不是由文件打開(kāi)方式?jīng)Q定的,而是由讀寫(xiě)函數(shù)決定的。
比如說(shuō),我們以二進(jìn)制文件的方式打開(kāi)一個(gè)文件(實(shí)際上只是指明了要進(jìn)行換行符的轉(zhuǎn)換),它更多的是代表一種理念(虛的):我“希望”這個(gè)文件里面的數(shù)據(jù)是這樣的,int類型占4字節(jié),char占1個(gè)字節(jié)。這種模式下,我用fread(buffer,size0f(int),1,fp)讀取一個(gè)int到int變量中。
這里需要記?。?/strong>
我們?cè)趯?duì)一個(gè)文件進(jìn)行操作以前,首先,我們要清楚這個(gè)文件到底是文本文件還是二進(jìn)制文件。文件文件用文本方式打開(kāi),二進(jìn)制文件用二進(jìn)制方式打開(kāi)
如果我們要操作一個(gè)二進(jìn)制文件,那么我們就以二進(jìn)制方式打開(kāi)(理論上也可以以文件方式打開(kāi),但是如果寫(xiě)的二進(jìn)制數(shù)據(jù)里面有45時(shí),會(huì)轉(zhuǎn)化成45,42存儲(chǔ),如前文所述。這是很有可能發(fā)生的)。同時(shí)讀寫(xiě)的時(shí)候用fread,fwrite這兩個(gè)函數(shù)。
如果我要操作一個(gè)文本文件,那么我們就以文本的方式打開(kāi)(理論上也可以以二進(jìn)制方式打開(kāi),但是不保險(xiǎn))。同時(shí)讀寫(xiě)的時(shí)候用讀寫(xiě)字符的那些函數(shù)fprintf,fscanf ,fgetc,fputc,putw,getw,fgetc,fputs.
上一篇:C++調(diào)用C#的DLL實(shí)現(xiàn)方法
欄 目:C語(yǔ)言
下一篇:VC小技巧匯總之窗口技巧
本文標(biāo)題:C語(yǔ)言采用文本方式和二進(jìn)制方式打開(kāi)文件的區(qū)別分析
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/3578.html
您可能感興趣的文章
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用函數(shù)刪除字符
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)式函數(shù)庫(kù)
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)數(shù)怎么表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫(xiě)分段 用c語(yǔ)言表示分段函數(shù)
- 04-02c語(yǔ)言編寫(xiě)函數(shù)冒泡排序 c語(yǔ)言冒泡排序法函數(shù)
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段函數(shù)
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎么打出三角函數(shù)的值
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求階乘


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫(xiě)分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫(xiě)函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 01-10C#中split用法實(shí)例總結(jié)
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 04-02jquery與jsp,用jquery
- 01-10delphi制作wav文件的方法