C語言文本方式和二進制方式打開文件區別


昨晚被@童老豬問到了兩者的區別,我以前覺得自己大概搞懂了,昨晚發現還是沒懂。今天查了一下資料,寫下自己的理解,以備以后查閱。

   我們都知道,文本文件和二進制文件在計算機上面都是以0,1存儲的,那么兩者怎么還存在差別呢?我覺得,對於編程人員,文本文件和二進制文件就是一個聲明,指明了你 應該以什么方式(文本方式/二進制)打開這個文件用什么函數讀寫這個文件(讀寫函數),怎么 判斷讀到這個文件結尾
   具體的說:
    1。以哪種方式打開一個文件?
   ANSI C規定了標准輸入輸出函數庫,用   fopen()函數打開文件。fopen()函數的調用方式一般為:

   FILE *fp;

   fp=fopen(文件名,使用文件方式);

   使用文件方式見下表:

使用文件方式

含義

"r"(只讀) 為輸入打開一個文本文件
"w"(只寫) 為輸出打開一個文本文件
"a"(追加) 為追加打開一個文本文件
"rb"(只讀) 為輸入打開一個二進制文件
"wb"(只寫) 為輸出打開一個二進制文件
"ab"(追加) 為追加打開一個二進制文件
"r+"(讀寫) 為讀/寫打開一個文本文件
"w+"(讀寫) 為讀/寫創建一個文本文件
"a+"(讀寫) 為讀/寫打開一個文本文件
"rb+"(讀寫) 為讀/寫打開一個二進制文件
"wb+"(讀寫) 為讀/寫創建一個二進制文件
"ab+"(讀寫) 為讀/寫打開一個二進制文件
   同一個文件從磁盤讀取文件到內存(程序數據區或者緩存區)時,兩種方式下,內存中的內容一般不相同,這就是 兩種打開方式的實質性差別
   這里要說一個背景,那就是在windows下,它會做一個處理,就是寫文件時,換行符會被轉換成回車,換行符存在磁盤文件上,而讀磁盤上的文件時,它又會進行逆處理,就是把文件中連續的回車,換行符轉換成換行符。
   因此,在讀取一個磁盤文件時,文本方式讀取到文件內容很有可能會比二進制文件短,因為文本方式讀取要把回車,換行兩個字符變成一個字符,相當於截短了文件。但是為什么僅僅是可能呢?因為可能文中中不存在連着的45,42這兩個字節(45是CR回車的ASCII碼,42是換行符CL的ASCII碼),也就不存在“截短”操作了,因此讀到的內容是一樣的。
   具體的來說,文件文件(以文本方式寫的),最好以文本方式讀。二進制文件(以二進制方式寫的),最好以二進制方式讀。不然可能會不正確。上面的已經分析了。
 2.以什么函數讀寫文件?
   數據怎么在磁盤上寫不是由文件打開方式決定的,而是由寫函數決定的。數據怎么從磁盤上讀也不是由文件打開方式決定的,而是由讀函數決定的。
   上面說的數據怎么寫是說指,一種類型的變量是怎么存的?比如int 12,可以直接存12的二進制碼(4個字節),也可以存字符1,字符2.
    數據怎么讀的是指,我要讀一個int變量,是直接讀sizeof(int)個字節,還是一個字符一個字符的讀,直到讀到的字符不是數字字符。
   C里面有兩組文件讀寫函數恰好支持上面兩種方式的讀寫:
   1.fread(buffer,size,count,fp), fwrite(buffer,size,count,fp)。用來讀寫一個數據塊。它對應的是第一種存儲方式。直接按類型的字節長度指定讀寫的字節數。
   2 fprintf函數和fscanf函數. 它對應的是第二種讀寫方式。即以字符的方式讀寫。( fprintf函數、fscanf函數與printf函數、scanf函數的作用相仿,都是格式化讀寫函數。fprintf和fscanf函數的讀寫對象是磁盤文件,而printf和scanf函數的讀寫對象是終端。)
    它們的一般調用格式為:

   fprintf(文件指針,格式字符串,輸出列表);

   fscanf (文件指針,格式字符串,輸入列表);

  3怎么判斷文件尾?

    在 C語言,或更精確地說成 C標准函式庫中,有一個特別的字符EOF(stdio.h中這個定義 #define EOF (-1) ,它表示:文件結束符(end of file)。在while循環中以EOF作為文件結束標志,這種以EOF作為文件結束標志的文件,必須是文本文件。在文本文件中,數據都是以字符的ASCII代碼值的形式存放。我們知道,ASCII代碼值的范圍是0~255,不可能出現-1,因此可以用EOF作為文件結束標志。

    但是,C語言中,當把數據以二進制形式存放到文件中時,就會有-1值的出現,此時不能采用EOF作為二進制文件的結束標志。為解決這個問題,ANSI C提供一個feof函數,用來判斷文件是否結束。如果遇到文件結束,函數feof(fp)的值為1,否則為0.

   feof函數既可用以判斷二進制文件是否結束,也可以用以判斷文本文件是否結束。但是要注意feof用以判斷文本文件尾時,如果代碼編寫不當,可能會把文本文中中的文件結束符EOF也讀取出來了;具體見http://baike.baidu.com/view/656648.htm

  4.知道一個文件是文本文件,還是二進制文件,更多的“提醒”我們,應該選擇哪種讀寫函數。

   正如2所說的,數據怎么存不是由文件打開方式決定的,而是由讀寫函數決定的。

   比如說,我們以二進制文件的方式打開一個文件(實際上只是指明了要進行換行符的轉換),它更多的是代表一種理念(虛的):我“希望”這個文件里面的數據是這樣的,int類型占4字節,char占1個字節。這種模式下,我用fread(buffer,size0f(int),1,fp)讀取一個int到int變量中。

  我們記住

 我們在對一個文件進行操作以前,首先,我們要清楚這個文件到底是文本文件還是二進制文件文件文件用文本方式打開,二進制文件用二進制方式打開

  如果我們要操作一個二進制文件,那么我們就以二進制方式打開(理論上也可以以文件方式打開,但是如果寫的二進制數據里面有45時,會轉化成45,42存儲,見1.這是很有可能發生的)。同時讀寫的時候用fread,fwrite這兩個函數。

 如果我要操作一個文本文件,那么我們就以文本的方式打開(理論上也可以以二進制方式打開,但是不保險)。同時讀寫的時候用讀寫字符的那些函數fprintf,fscanf ,fgetc,fputc,putw,getw,fgetc,fputs.

  4文本文件和二進制文件判斷

   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM