文本文件和二進制文件


http://blog.csdn.net/songjinshi/article/details/7789584

 

1、二進制文件是把內存中的數據按其在內存中的存儲形式原樣輸出到磁盤上存放,也就是說存放的是數據的原形式。


2、文本文件是把數據的終端形式的二進制數據輸出到磁盤上存放,也就是說存放的是數據的終端形式。

 

 

 

我們有必要把需要存儲的數據分為字符數據和非字符數據兩類。當你有數據要存儲的時候.首先要考慮的問題並不是你要選擇用二進制文件還是文本文件來進行存儲,而是首先得考慮你要存儲的數據是字符數據還是非字符數據.在此基礎上再討論應該選擇用什么文件進行存儲為好。

一、如果要存儲字符數據,無論是放在文本文件還是放在二進制文件中都和內存中的數據形式是沒有區別的.同樣也和終端形式沒有區別。那么在存儲和顯示的特性上也沒有任何區別,不浪費存儲空間也不浪費轉換時間。所以如果一個文件只存放字符數據,那么討論該文件是用文本文件或是二進制文件是沒有任何意義的。

二、如果要存儲非字符數據,則情況要復雜一些。

1、如果您需要頻繁地保存和訪問數據.那么應該采用二進制文件進行存放,這樣可以節省存儲空間和轉換時間。

2、如果您需要頻繁地向終端顯示數據或從終端讀人數據,那么應該采用文本文件進行存放,這樣可以節省轉換時間。

三、如果要存儲的數據中既有字符數據又有非字符數據那么要怎么辦呢?那就要綜合上述兩點進行權衡以找到最佳平衡點了

總結:字符數據本身在內存中就經過了編碼,所以無論是二進制還是文本形式都是一樣的,而對於非字符數據來說,例如inti=10;如果用二進制來進行存儲的話為1010,但是如果需要用文本形式來進行存儲的話就必須進行格式化編碼(對1和0分別編碼,即形式為‘1’和‘0’分別對應的碼值)

 

http://www.cnblogs.com/whutzhou/p/3215210.html

 

這里談談文本文件與二進制文件以及C語言讀寫這兩種文件的標准接口。

【具體到物理保存時都是二進制的,關鍵是保存前對數據的編碼有區別。】
文本文件與二進制文件在計算機文件系統中的物理存儲都是二進制的,也就是在物理存儲方面沒有區別都是01碼,這個沒有異議,他們的區別主要在邏輯存儲上,也就是編碼上。
文本文件格式存儲時是將值作為字符然后存入其字符編碼的二進制,文本文件用‘字符’作為單位來表示和存儲數據,比如對於1這個值,文本文件會將其看做字符‘1’然后保存其ASCII編碼值(這里假定是ASCII編碼),這樣在物理上就是0x31這個二進制值,而若是二進制保存1,則直接保存其二進制值,比如如果程序中是處理1為整數則保存的二進制值就是 0x00000001 (4字節)。
當然如果程序本來就是按字符保存的 也就是 char ch ='1' ; 則二進制保存后值就是其ASCII碼,因為該變量的二進制本來就是其ASCII碼。可以總結出二進制文件就是值本身的編碼,那么就是不定長的編碼了,因為值本身就是不等字節的,如整數4個字節那么保存在二進制文件就是這四個字節的原生二進制值。

綜上,可以知道文本文件與二進制文件就是編碼方式不一樣而已,而這個是用戶行為,把一個數據以什么樣的編碼(字符還是值本身)存入文件是由用戶主動選擇的,也就是寫入的接口選擇,如果以二進制接口方式寫入文件那么就是一個二進制文件,如果以字符方式寫入文件就是一個文本文件了。既然有寫入時候的編碼也就會有讀出的編碼,只有兩個編碼對應才能讀出正確的結果,如用記事本打開一個二進制文件會呈現亂碼的,這里稍微提一下后綴名,后綴名並不能確定其是否就是文本文件,二進制文件也可以是txt后綴名,后綴名只是用來關聯打開程序,給用戶做備注用的,與文件的具體編碼沒有關系。

可以使用字符接口讀寫二進制文件,只需要做些處理即可,所以所謂的二進制文件,文本文件主要體現在讀寫方式這里。
此外windows有一個明顯的區別是對待文本文件讀寫的時候,會將換行 \n自動替換成 \r\n。

最后文本文件和二進制文件主要是windows下的概念,UNIX/Linux並沒有區分這兩種文件,他們對所有文件一視同仁,將所有文件都看成二進制文件。

標准I/O庫中 主要使用 fread/fwrite來讀寫二進制文件,而對於文本文件可以使用 fread/fwrite fgetc/fputc fprintf等等

 

 

http://www.cppblog.com/yg2362/archive/2012/07/12/182956.html

      昨天在看一篇文章的時候,突然想起了這個基礎性的問題,自己一直對它的區別不是很清楚,於是今天上午研究下了,分享下自己的理解。(對它很清楚的同學們可以略過此篇文章)
      從存儲方式來說,文件在磁盤上的存儲方式都是二進制形式,所以,文本文件其實也應該算二進制文件。那么他們的區別呢,各自的優缺點呢?不急,我慢慢道來。
      先從他們的區別來說,雖然都是二進制文件,但是二進制代表的意思不一樣。打個比方,一個人,我們可以叫他的大名,可以叫他的小名,但其實都是代表這個人。二進制讀寫是將內存里面的數據直接讀寫入文本中,而文本呢,則是將數據先轉換成了字符串,再寫入到文本中。下面我用個例子來說明。
我們定義了一個結構體,表示一個學生信息,我們打算把學生的信息分別用二進制和文本的方式寫入到文件中。

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進制文件的可移植性好。

 

 

 

一、文本文件與二進制文件的定義

       大家都知道計算機的存儲在物理上是二進制的,所以文本文件與二進制文件的區
別並不是物理上的,而是邏輯上的。這兩者只是在編碼層次上有差異。

       簡單來說,文本文件是基於字符編碼的文件,常見的編碼有ASCII編碼,UNICOD
E編碼等等。二進制文件是基於值編碼的文件,你可以根據具體應用,指定某個值是什么
意思(這樣一個過程,可以看作是自定義編碼)。

       從上面可以看出文本文件基本上是定長編碼的,基於字符嘛,每個字符在具體編
碼中是固定的,ASCII碼是8個比特的編碼,UNICODE一般占16個比特。而二進制文件可看
成是變長編碼的,因為是值編碼嘛,多少個比特代表一個值,完全由你決定。大家可能
對BMP文件比較熟悉,就拿它舉例子吧,其頭部是較為固定長度的文件頭畔ⅲ??字節
用來記錄文件為BMP格式,接下來的8個字節用來記錄文件長度,再接下來的4字節用來記
錄bmp文件頭的長度。。。大家可以看出來了吧,其編碼是基於值的(不定長的,2、4、
8字節長的值都有),所以BMP是二進制文件。

二、文本文件與二進制文件的存取

       文本工具打開一個文件的過程是怎樣的呢?拿記事本來說,它首先讀取文件物理
上所對應的二進制比特流(前面已經說了,存儲都是二進制的),然后按照你所選擇的
解碼方式來解釋這個流,然后將解釋結果顯示出來。一般來說,你選取的解碼方式會是
ASCII碼形式(ASCII碼的一個字符是8個比特),接下來,它8個比特8個比特地來解釋
這個文件流。例如對於這么一個文件流"01000000_01000001_01000010_01000011"(下划
線''_'',是我為了增強可讀性,而手動添加的),第一個8比特''01000000''按ASCII碼來解
碼的話,所對應的字符是字符''A'',同理其它3個8比特可分別解碼為''BCD'',即這個文件
流可解釋成“ABCD”,然后記事本就將這個“ABCD”顯示在屏幕上。

        事實上,世界上任何東西要與其他東西通信會話,都存在一個既定的協議,既
定的編碼。人與人之間通過文字聯絡,漢字“媽”代表生你的那個人,這就是一種既定
的編碼。但注意到這樣一種情況,漢字“媽”在日本文字里有可能是你生下的那個人,
所以當一個中國人A與日本B之間用“媽”這個字進行交流,出現誤解就很正常的。用
記事本打開二進制文件與上面的情況類似。記事本無論打開什么文件都按既定的字符編
碼工作(如ASCII碼),所以當他打開二進制文件時,出現亂碼也是很必然的一件事情了
,解碼和譯碼不對應嘛。例如文件流''00000000_00000000_00000000_00000001''可能在二
進制文件中對應的是一個四字節的整數int 1,在記事本里解釋就變成了"NULL_NULL_NU
LL_SOH"這四個控制符。

  文本文件的存儲與其讀取基本上是個逆過程,不再累述。而二進制文件的存取顯然
與文本文件的存取差不多,只是編/解碼方式不同而已,也不再敘述。

  

三、文本文件與二進制文件的優缺點

  因為文本文件與二進制文件的區別僅僅是編碼上不同,所以他們的優缺點就是編碼
的優缺點,這個找本編碼的書來看看就比較清楚了。一般認為,文本文件編碼基於字符
定長,譯碼容易些;二進制文件編碼是變長的,所以它靈活,存儲利用率要高些,譯碼
難一些(不同的二進制文件格式,有不同的譯碼方式)。關於空間利用率,想想看,二
進制文件甚至可以用一個比特來代表一個意思(位操作),而文本文件任何一個意思至少
是一個字符.

  很多書上還認為,文本文件的可讀性要好些,存儲要花費轉換時間(讀寫要編譯碼)
,而二進制文件可讀性差,存儲不存在轉換時間(讀寫不要編解碼,直接寫值).這里
的可讀性是從軟件使用者角度來說的,因為我們用通用的記事本工具就幾乎可以瀏覽所
有文本文件,所以說文本文件可讀性好;而讀寫一個具體的二進制文件需要一個具體的
文件解碼器,所以說二進制文件可讀性差,比如讀BMP文件,必須用讀圖軟件.而這里的
存儲轉換時間應該是從編程的角度來說的,因為有些操作系統如windows需要對回車換行
符進行轉換(將''\n'',換成''\r\n'',所以文件讀寫時,操作系統需要一個一個字符的檢查
當前字符是不是''\n''或''\r\n'').這個在存儲轉換在Linux操作系統中並不需要,當然,當
在兩個不同的操作系統上共享文件時,這種存儲轉換又可能出來(如Linux系統和Window
s系統共享文本文件)。關於這個轉換怎樣進行,我將在下一篇文章《Linux文本文件與W
indows文本文件間的轉換》給出^_^

四、C的文本讀寫和二進制讀寫

  應該說C的文本讀寫與二進制的讀寫是一個編程層次上的問題,與具體的操作系統
有關,所以"用文本方式讀寫的文件一定是文本文件,用二進制讀寫的文件一定是二進
制文件"這類觀點是錯誤的.下面的講述非明確指出操作系統類型,都暗指windows.

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

   總地來說,從編程的角度來說,C中文本或二進制讀寫都是緩沖區與文件中二進
制流的交互,只是文本讀寫時有回車換行的轉換.所以當寫緩沖區中無換行符''\n''(0AH
),文本寫與二進制寫的結果是一樣的,同理,當文件中不存在''\r\n''(0DH0AH)時,文本
讀與二進制讀的結果一樣.

   下面給出一個小程序來證明前面的觀點.

1、編寫如下程序.該程序將字符串"12\n3"分別以文本方式和二進制方式寫入test1和t
est2,然后再以文本方式

讀test1,以二進制方式讀test2.

#include<stdio.h>

int main()

{

    FILE * fp_text,* fp_binary;

    char write_buf[4]={''1'',''2'',''\n'',''3''};

    char read_buf_text[6],read_buf_binary[6];

    int read_count_text,read_count_binary;

    //未檢測打開是否失敗

    fp_text=fopen("test1","wt+");

    fp_binary=fopen("test2","wb+");

    fwrite(write_buf,4,1,fp_text);

    fwrite(write_buf,4,1,fp_binary);

    //fflush(fp_text);

    //fflush(fp_binary);

 

    fseek(fp_text,0L,SEEK_SET);//fseek附帶了fflush功能

    fseek(fp_binary,0L,SEEK_SET);//

    read_count_text=fread(read_buf_text,sizeof(char),5,fp_text);

    read_count_binary=fread(read_buf_binary,sizeof(char),5,fp_binary);

    //加''\0'',便於打印字符串

    read_buf_text[read_count_text]=''\0'';

    read_buf_binary[read_count_binary]=''\0'';

    printf("In Text Mode:read_count=%d,string=%s\n",read_count_text,read_buf
_text);

    printf("In Binary Mode:read_count=%d,string=%s\n",read_count_binary,read
_buf_binary);

    fclose(fp_text);

    fclose(fp_binary);

    return 0;

   

}

2、該程序在VC6.0下編譯運行,顯示結果如下(追憶"\\"及其右邊內容是我手動加的注釋
):

 In Text Mode:read_count=4,string=12

  3                           //文本方式讀test1,讀到的字符與原先寫入test1的
字符一樣

  In Binary Mode:read_count=4,string=12

  3                           //二進制方式讀test1,讀到的字符與原先寫入test1
的字符一樣

  3.用記事本打開test1和test2,結果如下

  test1的內容:

 12

  3           //文本方式寫入的,有換行效果,參看下面的4

  test2的內容

  123         //二進制方式寫入的,無換行效果(記事本對"\r\n"之外的控制字符串無
顯示效果),參看下面的4

4、用vc6.0以Binary方式(二進制方式)打開test1和test2,結果如下(用其他二進制讀
寫軟件也可以) 

  test1的內容

  31 32 0D 0A 33//十六進制,5個字節,比寫入緩沖區多了一個字節,在''\n''(0AH)前
插了一個''\r''(0DH)

  test2的內容

  31 32 0A 33//十六進制,4個字節,與寫入緩沖區的值一致.

 

 5、總結

     從4可以看出,文本方式寫時,存在''\n''->''\r\n''的轉換,而二進制方式無轉換.
又從2和4可以推出,文本方式讀時存在''\r\n''->至''\n''的轉換,而二進制方式無轉換.
有興趣的讀者可以,以二進制方式讀test1或以文本方式讀test2,看會出現什么效果

  6.補充說明

   上述說明僅適用於windows,在linux中文本方式的讀寫與二進制方式的讀寫無差
別,不存在回車換行間的轉換
.這樣當直接在windows和linux中共享文件時,將會出現
與回車換行相關的問題.下一篇文章《Linux文本文件與Windows文本文件間的轉換》將
給出Linux文本文件與Windows文本文件間轉換的C程序,敬請關注^_^

 

轉自: http://blogold.chinaunix.net/u2/60332/showart_2098775.html


免責聲明!

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



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