文件讀寫: 二進制方式和文本方式的區別

 首先要明白一點,就是無論你用哪種語言進行程序設計,也無論你用哪個函數進行文件操作(庫函數也好,直接操作系統API也好),最終的文件打開的操作都是由操作系統來進行的,因此各種語言的情況從本質上來說都是相同的。


  用二進制模式打開一個文件的時候,文件本身的內容和你編寫程序時用函數讀到的內容完全相同(或者說和磁盤上的內容完全相同)。

  但是如果用了文本模式,那麼操作系統在將文件內容傳給上層程序(庫函數,或者是你的程序)時,或者上層程序通過操作系統向文件寫入內容時,操作系統都會預先進行一層預處理(或者說轉義),具體過程依賴於操作系統的實現。在Windows+VC下,最常見就是將回車符"\r\n"(沒有引號,且\作轉義符用,下同)解釋成"\n"(讀出時),將"\n"解釋成"\r\n"(寫入時)。而在Linux下沒有這層轉換,這也是Windows和Linux文本文件不通用的原因。

  除此以外,兩種打開方式其實是大同小異的。
  舉個例子,設有一文件file.dat內容爲"ABC\r\nABC",那麼在下面的代碼中,讀到的內容將是"ABC\r\nABC":
  fp = fopen("file.dat","rb"); 
  while(fgetc(fp)!=EOF);
  而在下面的代碼中,讀到的內容卻是"ABC\nABC":
  fp = fopen("file.dat","rt"); 
  while(fgetc(fp)!=EOF);

  還有一點要注意的是關於文件定位的問題。在文本模式下最好少用fseek,因爲有了庫函數的那層轉義的存在,fseek會有一些近乎於奇怪的行爲。我在Windows+VC下試驗發現,儘管在文本模式下"\r\n"還是被當作兩個字符計算的,但是當你把文件指針定位到"\r\n"處時,讀到的兩個字節都是"\n"。

 

        C的文本方讀寫與二進制讀寫的差別僅僅體現在回車換行符的處理上.文本方式寫時,每遇到一個''\n''(0AH換行符),它將其換成''\r\n''(0D0AH,回車換行),然後再寫入文件;當文本讀取時,它每遇到一個''\r\n''將其反變化爲''\n'',然後送到讀緩衝區.正因爲文本方式有''\n''--''\r\n''之間的轉換,其存在轉換耗時.二進制讀寫時,其不存在任何轉換,直接將寫緩衝區中數據寫入文件.

 

 

二進制讀寫是將內存裏面的數據直接讀寫入文本中,而文本呢,則是將數據先轉換成了字符串,再寫入到文本中。下面我用個例子來說明。
我們定義了一個結構體,表示一個學生信息,我們打算把學生的信息分別用二進制和文本的方式寫入到文件中。
struct Student 
{
    
int num;
    
char name[20];
    
float score;
};
我們定義兩個方法,分別表示內存寫入和文本寫入
//使用二進制寫入
void write_to_binary_file()
{
    
struct Student stdu;
    stdu.num 
= 111;
    sprintf_s(stdu.name,
20,"%s","shine");
    stdu.score 
= 80.0f;
    fstream binary_file(
"test1.dat",ios::out|ios::binary|ios::app); //此處省略文件是否打開失敗的判斷
    binary_file.write((char *)&stdu,sizeof(struct Student));//二進制寫入的方式
    binary_file.close();

//文本格式寫入
void write_to_text_file()
{
    
struct Student stdu;
    stdu.num 
= 111;
    sprintf_s(stdu.name,
20,"%s","shine");
    stdu.score 
= 80.0f;
    FILE 
*fp = fopen("test2.dat","a+");   //此處省略文件是否打開失敗的判斷
    fprintf(fp,"%d%s%f",stdu.num,stdu.name,stdu.score); //將數據轉換成字符串(字符串的格式可以自己定義)
    fclose(fp);

//MAIN函數調用前面兩個方法
int _tmain(int argc, _TCHAR* argv[])
{
    write_to_binary_file();
    write_to_text_file();
    
    
return 0;
}
我們來看下,文件裏面的格式 2進制文件

文本文件


2進制文件裏面將111編碼成6F,1個字節,這剛好是111的16進製表示,而文本文件中則寫成31,31,31用了3個字節,表示111。73   68   69   6E   65 表示shine,之後2進制文件裏是幾個連續的FE,而文本文件中是38   30......文本文件將浮點數80.000000用了38(表示8)   30(表示0)  2E(表示.)   30(表示0)   30(表示0)   30(表示0)   30(表示0)   30(表示0)   30(表示0),二進制文件用了4個字節表示浮點數00   00   A0   42
通過這裏我們可以初見端倪了,二進制將數據在內存中的樣子原封不動的搬到文件中,文本格式則是將每一個數據轉換成字符寫入到文件中,他們在大小上,佈局上都有着區別。由此可以看出,2進制文件可以從讀出來直接用,但是文本文件還多一個“翻譯”的過程,因此2進制文件的可移植性好。

發佈了45 篇原創文章 · 獲贊 12 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章