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