廣義上的二進制文件包括文本文件,這里討論的是狹義上的二進制文件與文本文件的比較:
- 能存儲的數據類型不同
文本文件只能存儲char型字符變量。二進制文件可以存儲char/int/short/long/float/……各種變量值。 - 每條數據的長度
文本文件每條數據通常是固定長度的。以ASCII為例,每條數據(每個字符)都是1個字節。進制文件每條數據不固定。如short占兩個字節,int占四個字節,float占8個字節…… - 讀取的軟件不同
文本文件編輯器就可以讀寫。比如記事本、NotePad++、Vim等。二進制文件需要特別的解碼器。比如bmp文件需要圖像查看器,rmvb需要播放器…… - 操作系統對換行符(‘\n’)的處理不同(不重要)
文本文件,操作系統會對’\n’進行一些隱式變換,因此文本文件直接跨平台使用會出問題。
在Windows下,寫入’\n’時,操作系統會隱式的將’\n’轉換為”\r\n”,再寫入到文件中;讀的時候,會把“\r\n”隱式轉化為’\n’,再讀到變量中。
在Linux下,寫入’\n’時,操作系統不做隱式變換。
二進制文件,操作系統不會對’\n’進行隱式變換,很多二進制文件(如電影、圖片等)可以跨平台使用。
從存儲方式來說,文件在磁盤上的存儲方式都是二進制形式,所以,文本文件其實也應該算二進制文件。先從他們的區別來說,雖然都是二進制文件,但是二進制代表的意思不一樣。打個比方,一個人,我們可以叫他的大名,可以叫他的小名,但其實都是代表這個人。二進制讀寫是將內存里面的數據直接讀寫入文本中,而文本呢,則是將數據先轉換成了字符串,再寫入到文本中。
要弄明白二者的區別,需要知道文件的讀寫過程。以讀文件為例,
實際上是磁盤 》》 文件緩沖區》》應用程序內存空間這兩個轉化過程。我們說“文本文件和二進制文件沒有區別”,實際上針對的是第一個過程;既然沒有區別,那么打開方式不同,為何顯示內容就不同呢?這個區別實際上是第二個過程造成的。
文件實際上包括兩部分,控制信息和內容信息。純文本文件僅僅是沒有控制格式信息罷了;
實際上也是一種特殊的二進制文件。所以,我們很難區分二者的不同,因為他們的概念上不是完全互斥的。我們說文本文件是特殊的二進制文件,是因為文本文件實際上的解釋格式已經確定了:ASCII或者unicode編碼。文本文件的一個缺點是,它的熵往往較低,也就是說,其實本可以用更小的存儲空間記錄這些信息。比如,文本文件中的一個數字65536,需要用5個字節來存儲;但是用二進制格式,采用int存儲,僅僅需要2個字節。而二進制文件elf和bmp等,都往往有一個head,告訴你文件信息和解釋方式。
記事本支持文本文件而不支持二進制文件,所以如果你用記事本打開文本文件那么一切正常,如果打開的是二進制文件就會出現亂碼。但也有不亂碼的地方,你會注意到那些地方都是字符編碼的,而對於int、double等類型所對應的值都是亂碼的,這是由於記事本只能夠識別字符類型,而無法識別其他類型。
1、二進制文件是把內存中的數據按其在內存中的存儲形式原樣輸出到磁盤上存放,也就是說存放的是數據的原形式。
2、文本文件是把數據的終端形式的二進制數據輸出到磁盤上存放,也就是說存放的是數據的終端形式。
字符數據本身在內存中就經過了編碼,所以無論是二進制還是文本形式都是一樣的,而對於非字符數據來說,例如inti=10;如果用二進制來進行存儲的話為1010,但是如果需要用文本形式來進行存儲的話就必須進行格式化編碼(對1和0分別編碼,即形式為‘1’和‘0’分別對應的碼值)。
一、文本文件與二進制文件的定義
大家都知道計算機的存儲在物理上是二進制的,所以文本文件與二進制文件的區別並不是物理上的,而是邏輯上的。這兩者只是在編碼層次上有差異。簡單來說,文本文件是基於字符編碼的文件,常見的編碼有ASCII編碼,UNICODE編碼等等。二進制文件是基於值編碼的文件,你可以根據具體應用,指定某個值是什么意思(這樣一個過程,可以看作是自定義編碼。
從上面可以看出文本文件基本上是定長編碼的(也有非定長的編碼如UTF-8)。而二進制文件可看成是變長編碼的,因為是值編碼嘛,多少個比特代表一個值,完全由你決定。大家可能對BMP文件比較熟悉,就拿它舉例子吧,其頭部是較為固定長度的文件頭信息,前2字節用來記錄文件為BMP格式,接下來的8個字節用來記錄文件長度,再接下來的4字節用來記錄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_NULL_SOH”這四個控制符。
文本文件的存儲與其讀取基本上是個逆過程。而二進制文件的存取顯然與文本文件的存取差不多,只是編/解碼方式不同而已。
三、文本文件與二進制文件的優缺點
因為文本文件與二進制文件的區別僅僅是編碼上不同,所以他們的優缺點就是編碼的優缺點,這個找本編碼的書來看看就比較清楚了。一般認為,文本文件編碼基於字符定長,譯碼容易些;二進制文件編碼是變長的,所以它靈活,存儲利用率要高些,譯碼難一些(不同的二進制文件格式,有不同的譯碼方式)。關於空間利用率,想想看,二進制文件甚至可以用一個比特來代表一個意思(位操作),而文本文件任何一個意思至少是一個字符。
在windows下,文本文件不一定是一ASCII來存貯的,因為ASCII碼只能表示128的標識,你打開一個txt文檔,然后另存為,有個選項是編碼,可以選擇存貯格式,一般來說UTF-8編碼格式兼容性要好一些.而二進制用的計算機原始語言,不存貯兼容性. 很多書上還認為,文本文件的可讀性要好些,存儲要花費轉換時間(讀寫要編譯碼),而二進制文件可讀性差,存儲不存在轉換時間(讀寫不要編解碼,直接寫值).這里的可讀性是從軟件使用者角度來說的,因為我們用通用的記事本工具就幾乎可以瀏覽所有文本文件,所以說文本文件可讀性好;而讀寫一個具體的二進制文件需要一個具體的文件解碼器,所以說二進制文件可讀性差,比如讀BMP文件,必須用讀圖軟件。
而這里的存儲轉換時間應該是從編程的角度來說的,因為有些操作系統如windows需要對回車換行符進行轉換(將”\n”,換成”\r\n”,所以文件讀寫時,操作系統需要一個一個字符的檢查當前字符是不是”\n”或”\r\n”).這個在存儲轉換在Linux操作系統中並不需要,當然,當在兩個不同的操作系統上共享文件時,這種存儲轉換又可能出來。
文本文件是一種計算機文件,它是一種典型的順序文件,其文件的邏輯結構又屬於流式文件。
特別的是,文本文件是指以ASCII碼方式(也稱文本方式)存儲的文件,更確切地說,英文、數字等字符存儲的是ASCII碼,而漢字存儲的是機內碼。文本文件中除了存儲文件有效字符信息(包括能用ASCII碼字符表示的回車、換行等信息)外,不能存儲其他任何信息。
文本文件是一種由若干行字符構成的計算機文件。文本文件存在於計算機文件系統中。通常,通過在文本文件最后一行后放置文件結束標志來指明文件的結束。文本文件是指一種容器,而純文本是指一種內容。文本文件可以包含純文本。一般來說,計算機文件可以分為兩類:文本文件和二進制文件。
只含有ASCII字符的文本文件可以在Unix、Macintosh、Microsoft Windows、DOS和其它操作系統之間自由交互,而其它格式的文件是很難做到這一點的。但是,在這些操作系統中,換行符並不相同,處理非ASCII字符的方式也不一致。
.txt是包含極少格式信息的文字文件的擴展名。.txt格式並沒有明確的定義,它通常是指那些能夠被系統終端或者簡單的文本編輯器接受的格式。任何能讀取文字的程序都能讀取帶有.txt擴展名的文件,因此,通常認為這種文件是通用的、跨平台的。
在英文文本文件中,ASCII字符集是最為常見的格式,而且在許多場合,它也是默認的格式。對於帶重音符號的和其它的非ASCII字符,必須選擇一種字符編碼。在很多系統中,字符編碼是由計算機的區域設置決定的。常見的字符編碼包括支持許多歐洲語言的ISO 8859-1。
由於許多編碼只能表達有限的字符,通常它們只能用於表達幾種語言。Unicode制定了一種試圖能夠表達所有已知語言的標准,Unicode字符集非常大,它囊括了大多數已知的字符集。Unicode有多種字符編碼,其中最常見的是UTF-8,這種編碼能夠向后兼容ASCII,相同內容的的ASCII文本文件和UTF-8文本文件完全一致。
微軟的MS-DOS和Windows采用了相同的文本文件格式,它們都使用CR和LF兩個字符作為換行符,這兩個字符對應的ASCII碼分別為13和10。通常,最后一行文本並不以換行符(CR-LF標志)結尾,包括記事本在內的很多文本編輯器也不在文件的最后添加換行符。
大多數Windows文本文件使用ANSI、OEM或者Unicode編碼。Windows所指的ANSI編碼通常是1字節的ISO-8859編碼,不過對於像中文、日文、朝鮮文這樣的環境,需要使用2字節字符集。在過渡至Unicode前,Windows一直用ANSI作為系統默認的編碼。而OEM編碼,也是通常所說的MS-DOS代碼頁,是IBM為早期IBM個人電腦的文本模式顯示系統定義的。在全屏的MS-DOS程序中同時使用了圖形的和按行繪制的字符。新版本的Windows可以使用UTF-16LE和UTF-8之類的Unicode編碼。
由於結構簡單,文本文件被廣泛用於記錄信息。它能夠避免其它文件格式遇到的一些問題。此外,當文本文件中的部分信息出現錯誤時,往往能夠比較容易的從錯誤中恢復出來,並繼續處理其余的內容。文本文件的一個缺點是,它的熵往往較低,也就是說,可以用較小的存儲空間記錄這些信息。
文本文件基本上是定長編碼的(也有非定長的編碼如UTF-8),基於字符,每個字符在具體編碼中是固定的,ASCII碼是8個比特的編碼,UNICODE一般占16個比特。而二進制文件可看成是變長編碼的,因為是值編碼,多少個比特代表一個值,完全由自己決定。
廣義的二進制文件即指文件,由文件在外部設備的存放形式為二進制而得名。狹義的二進制文件即除文本文件以外的文件。
每個字符由一個或多個字節組成,每個字節都是用的-128—127之間的部分數值來表示的,也就是說,-128——127之間還有一些數據沒有對應任何字符的任何字節。如果一個文件中的每個字節的內容都是可以表示成字符的數據,我們就可以稱這個文件為文本文件。文本文件只是二進制文件中的一種特例,為了與文本文件相區別,人們又把除了文本文件以外的文件稱為二進制文件,由於很難嚴格區分文本文件和二進制文件的概念,所以我們可以簡單地認為,如果一個文件專門用於存儲文本字符的數據,沒有包含字符以外的其他數據,我們就稱之為文本文件,除此之外的文件就是二進制文件。
為什么要使用二進制文件。原因大概有三個:
第一是二進制文件比較節約空間,這兩者儲存字符型數據時並沒有差別。但是在儲存數字,特別是實型數字時,二進制更節省空間;第二個原因是,內存中參加計算的數據都是用二進制無格式儲存起來的,因此,使用二進制儲存到文件就更快捷。如果儲存為文本文件,則需要一個轉換的過程。在數據量很大的時候,兩者就會有明顯的速度差別了。第三,就是一些比較精確的數據,使用二進制儲存不會造成有效位的丟失。