二进制文件与文本文件详解
二進制文件
-  定義: 二進制文件就是把內存中的數據按其在內存中存儲的形式原樣輸出到磁盤中存放,即存放的是數據的原形式。二進制文件是包含在 ASCII 及擴展 ASCII 字符中編寫的數據或程序指令的文件。一般是可執行程序、圖形、聲音等文件,有自己特殊的編解碼格式。不同的應用程序對二進制文件中的每個值會有不同的解讀,要打開二進制文件需要對應的二進制文件解碼器。 
-  讀取流程: 用記事本打開二進制文件的流程是怎樣的呢?記事本無論打開什么文件都按既定的字符編碼工作(如ASCII碼),用ASCII碼的規則去解讀二進制文件時,會出現亂碼。所以當他打開二進制文件時,出現亂碼也是很必然的一件事情,解碼和譯碼不對應。例如文件流”00000000_00000000_00000000_00000001”可能在二進制文件中對應的是一個四字節的整數int 1,在記事本里解釋就變成了”NULL_NULL_NULL_SOH”這四個控制符。文本文件將浮點數80.000000用了38(表示8) 30(表示0) 2E(表示.) 30(表示0) 30(表示0) 30(表示0) 30(表示0) 30(表示0) 30(表示0),二進制文件用了4個字節表示浮點數00 00 A0 42。字符型的內容都是ASCii碼的形式,沒有區別。 
-  例子: 在計算機中,所有的顏色都可以映射為一個二進制的值。圖片存儲時,圖片上每個點都有自己的顏色值,將每個點的顏色值,以及圖片本身的寬高信息儲存起來,就是最基本的位圖存儲(bmp),位圖存儲是沒有壓縮的。將位圖信息,經過二次編碼,壓縮就形成了壓縮后的圖片。算法不同產生的圖片格式也有區別。常見的包括jpg,png,gif等。文本文件基本上是定長編碼的(也有非定長的編碼如UTF-8)。而二進制文件可看成是變長編碼的,因為是值編碼,多少個比特代表一個值,完全由自定義的編解碼規則決定。像BMP文件,其頭部是較為固定長度的文件頭信息,前2字節用來記錄文件為BMP格式,接下來的8個字節用來記錄文件長度,再接下來的4字節用來記錄bmp文件頭的長度。 
-  linux 二進制的兼容性: Linux上二進制有一個顯著的特點就是可移植性不強。我們在不同的發行版之間,不同的內核版本之間,程序往往是不能通用的,比如把ubunbtu下面編譯的二進制可執行文件拷貝到CentOS上,基本不可能運行。原因是程序總需要使用或多或少的系統調用,系統調用是核心代碼實現的,核心不同自然也就不兼容了。另外不同系統的對執行文件加載方式也不同。 
 如果應用對內核kernel版本有要求,則不建議使用docker,docker底層復用的host的kernel.,如果可以用docker,可以解決除kernel版本外的兼容性問題,build once run everywhere。
文本文件
-  定義: 文本文件是把數據的終端形式的二進制數據輸出到磁盤上存放,即存放的是數據的終端形式. 文本文件(也稱為ASCII文件):它的每一個字節存放的是可表示為一個字符的ASCII代碼的文件。它是以 “行”為基本結構的一種信息組織和存儲方式的文件,可用任何文字處理程序閱讀的簡單文本文件。 
-  讀取流程: 文本工具打開一個文件的過程是怎樣的呢?拿記事本來說,它首先讀取文件物理上所對應的二進制比特流,然后按照你所選擇的解碼方式來解釋這個流,然后將解釋結果顯示出來。一般來說,你選取的解碼方式會是ASCII碼形式(ASCII碼的一個字符是8個比特),接下來,它8個比特8個比特地來解釋這個文件流。例如對于這么一個文件流”01000000_01000001_01000010_01000011”, 第一個8比特”01000000”按ASCII碼來解碼的話,所對應的字符是字符”A”,同理其它3個8比特可分別解碼為”BCD”,即這個文件流可解釋成“ABCD”,然后記事本就將這個“ABCD”顯示在屏幕上。 
-  選擇: 如果是需要頻繁的保存和訪問數據,那么應該采取二進制文件進行存放,這樣可以節省存儲空間和轉換時間。 
 如果需要頻繁的向終端顯示數據或從終端讀入數據,那么應該采用文本文件進行存放,這樣可以節省轉換時間。
-  區別: window 文本模式中,在存儲\n時要轉化為\r\n,讀取文件時進行逆轉換。window二進制模式時,則不進行轉換。 
-  ^m原因: 回車和換行是不相同的,Windows中文字另起一行內存表示為<回車><換行>對應\r\n,而Linux、Unix中則是單單一個<換行>對應\n。Mac中則是一個<回車>對應\r。C語言起源于Unix的產生,對于文件中的另起一行,Unix采用單個\n表示,我們通常在輸出換行時加一個\n就可以了,Windows也是如此。到了數據從內存到硬盤上進行存儲時,對于unix來說,\n照樣是\n,在Linux下,二進制文件和文本文件都是以’\n’作為行結束符,所以不需要轉換,而Windows為了防止讀取時混亂必須轉換為\r\n。Windows 格式的文本文件,用\r\n 作為換行符,而Unix 的則是以\n作為換行符,所以dos 底下的文本文件到了unix的話,換行符就會多出來一個 0D(CR) 顯示為 ^M。 
結構體寫入文件
- 結構體寫入文件:C語言把文件看作一個字符(字節)的序列,即由一個一個字符(字節)的數據順序組成。根據數據的組織形式,可分為ASCII文件和二進制文件。ASCII文件又稱為文本(text)文件,它的每個字節放一個ASCII代碼,代表一個字符。二進制文件是把內存中的數據按其在內在中的存儲形式原樣輸出到磁盤上存放。二進制將數據在內存中的樣子原封不動的搬到文件中,文本格式則是將每一個數據轉換成字符寫入到文件中,他們在大小上,布局上都有著區別。由此可以看出,二進制文件可以讀出來直接用,但是文本文件還多一個“翻譯”的過程,因此二進制文件的可移植性好。
- C語言把一個結構體數組寫入文件分三步:
 1、以二進制寫方式(wb)打開文件
 2、調用寫入函數fwrite()將結構體數據寫入文件
 3、關閉文件指針
 相應的,讀文件也要與之匹配:
 1、以二進制讀方式(rb)打開文件
 2、調用讀文件函數fread()讀取文件中的數據到結構體變量
 3、關閉文件指針
- fwrite :函數按照指定的數據類型將矩陣中的元素寫入到文件中。寫二進制文件其調用格式為:COUNT=fwrite (fd, A, precision)其中COUNT返回所寫的數據元素個數,fd為文件句柄,A用來存放寫入文件的數據,precision用于控制所寫數據的類型,其形式與fread函數相同。當我們按照二進制方式往文件中寫入數據,則將數據在內存中的存儲形式原樣輸出到文件中。用fwrite 寫入文件的如果是字符,那么就會顯示為字符,寫入的是數字顯示不出來,寫的是二進制內容(所謂的亂碼)
- fprintf :寫文本文件 函數的調用格式為:COUNT= fprintf(fd, format, A)其中A存放要寫入文件的數據。先按format指定的格式將數據矩陣A格式化,然后寫入到fid所指定的文件。format用以控制讀取的數據格式,由%加上格式符組成,常見的格式符有d,f,c,s。fid為文件句柄。fprintf寫的是數字轉換成ASCII碼之后的字符。
- 當使用fwrite將一個int型數字65寫入文本文件時,由于65對應的二進制數是1000001,十六進制數是0x41,存儲的是以二進制的形式1000001.在notepad++中使用十六進制方式打開顯示的是:0x0041,轉換為十進制則為65。記事本打開可能存在亂碼,因為fwrite在寫入的時候是采用整字節的二進制寫入,而文本編輯器采用的是ascll碼顯示,兩者不兼容。
- 當使用fpintf將一個int型數字65寫入文本文件時,將65每一位轉換為ASCII碼存儲,6、5分別對應ASCII碼54、53,存儲的是ASCII碼54、53.在notepad++中使用十六進制方式打開顯示的是:3635,轉換為十進制則為54、53,這正是數字6、5的ASCII碼。使用記事本打開這個文本文件時,記事本將存儲在其中的54、53當做ASCII碼翻譯為字符6、5顯示,我們看到的是便是字符65。
- 二進制讀寫是將內存里面的數據直接讀寫入文本中,而文本呢,則是將數據先轉換成了字符串,再寫入到文本中。下面我用個例子來說明。
 我們定義了一個結構體,表示一個學生信息,我們打算把學生的信息分別用二進制和文本的方式寫入到文件中。
二進制 圖
 
 文本文件 圖
 
- stdu.num = 111: 二進制文件里面將111編碼成6F,1個字節,這剛好是111的16進制表示,而文本文件中則寫成31 31 31用了3個字節,表示111。
- stdu.name = “shine”: 二進制和文本文件中73 68 69 6E 65都表示shine,這體現對字符數據處理的一致性。
- stdu.score = 80.0f: 二進制文件里是幾個連續的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
- 通過這里我們可以初見端倪了,二進制將數據在內存中的樣子原封不動的搬到文件中,文本格式則是將每一個數據轉換成字符寫入到文件中,他們在大小上,布局上都有著區別。由此可以看出,二進制文件可以從讀出來直接用,但是文本文件還多一個“翻譯”的過程,因此二進制文件的可移植性好。
總結
以上是生活随笔為你收集整理的二进制文件与文本文件详解的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: docker搜索镜像
- 下一篇: BZOJ 4278: [ONTAK201
