1. 程式人生 > >位元組流、字元流、ascii、gb2312、gbk、gb18030、亂碼、什麼時候使用位元組流,什麼時候使用字元流,二者區別。分分鐘透徹理解。

位元組流、字元流、ascii、gb2312、gbk、gb18030、亂碼、什麼時候使用位元組流,什麼時候使用字元流,二者區別。分分鐘透徹理解。

早先在 Java IO包裡面出現的都是位元組流,因為資料,無論是硬碟上的還是記憶體中的,都是位元組,都是二進位制資料10101的方式進行傳輸或儲存的。

那麼為什麼後來又出現了個字元流的概念呢?
在我們處理資料的時候,資料的種類有很多,比如dvd,圖片,文字,mp3等對於dvd,mp3等都是媒體資料,無論什麼資料都是二進位制的,0101之類的方式存在的。所以無論什麼資料位元組流都可以搞定。但是其中有一部分是文字資料,這個是比較常見和常用的,為了方便處理這類資料。單獨分離出來個字元流,來處理這類特殊常用的資料型別。

單獨分離出來字元流,到底哪方便了呢?
字元流的由來:
(無證可考,我道聽途說的。)
想要在計算機裡面,識別我們日常生活中的一些資料。計算機是美國人發明的,美國人的生活當中,都是些字母,abcd。。。但是計算機只能識別010101,二進位制數。那麼就用1010,這個排列組合和字母形成一個一一對應的對映表,比如:a的對應數字就97,等等很多對應關係。想到沒有,就是上學時候,說的就是ascii碼錶。有了這個表,計算機就可以識別美國人的字母和一些標點符號啦,然後,計算機到了中國,為了讓計算也能夠認識中國的漢字,哎,我們就向美國人學習,也整出來一個表:漢字和1010對應的表,來對應中國的漢字。這張表叫做GB2312,這個表收錄了幾千個中文漢字和標點符號,但是中文博大精深,幾千個哪夠啊,所以後來又進行了一次擴容。擴容升級之後叫做GBK,上了兩萬多的內容,但是還是不夠用吧。後面就繼續擴容,想想上學時候,你用的新華字典。估計都搬進去啦。然後就有了GB18030,然後呢,上升到國際層面來上說。國際標準化組織就琢磨這事啦。這不行啊。一個國家整個表,這的整多少個碼錶呢。所以,他們覺得:哎,咱們一共就整一個表,把地球上能用的語言都整進來。然後就把各個國家的文字都給整進來,進行編排,用數字進行編排,弄了個國際性的碼錶,叫做unicode碼錶,然後,後期又進行了優化,然後這就是現在常用的utf-8碼錶的由來。

為啥Unicode要升級為utf-8呢?

Unicode裡面無論什麼字元,都必須用2個位元組表示,一個位元組8個二進位制位,那麼每個都要用16位來表示一個字元,比如a,97,一個8位二進位制就夠了,用2個浪費空間啦。後期的utf-8就對此做了優化:一個位元組夠用就用一個,不夠用,用2個,還不夠,用3個,肯定夠了。漢字好像是2個位元組,也就是佔16位。

亂碼的由來:
現在假設我用gbk的編碼方式,把“您”這個字給存到電腦上,存起來的資料都是二進位制的格式喲,別忘記了哈,這個二進位制的數字,是根據gbk這個碼錶來判斷的"您"對應的到底是數字幾假設是數字99吧,然後,寫到硬碟上。然後,你到另一臺電腦上,他的電腦上是utf-8的編碼格式,那麼在這個utf-8的碼錶上讀99對應的字元,那就不一定是漢字“您”了。所以亂碼就由此而產生了。 

為了解決亂碼問題,Java出現了字元流。

Java在流技術上,在位元組流的基礎上,出現了字元流。這個字元流出現的好處有什麼呢?他可以在內部融合編碼表,也就是說,你讀到的這個位元組資料,你到底是查的哪個編碼表,到底是查gbk的碼錶,還是查utf-8碼錶,可以由我們自己來指定,這樣我們在處理文字的時候,就可以很方便。這個就是字元流的由來。

簡單一句話:字元流的這些物件裡面,融合了編碼表,只有文字適合編碼。

所以,字元流適合處理文字。假如當前我想處理圖片,那麼就用位元組流來處理,為什麼?總不至於,你把圖片的資料讀出來以後,在把資料進行編碼表查詢,換成文字,一美女圖片,你查出來,變成一堆文字,這不合適吧。
通用的是位元組流,字元流是基於位元組流。

最後就是在Java的io體系裡面一共有四個抽象基類

位元組流:InputStream和OutputStream(面向的是計算機,是基礎,方便計算機處理)
字元流:Reader和Writer(面向的是人類,方便人類處理文字)

到這裡,什麼位元組流,字元流,gbk,utf-8,亂碼,啥的,不都分分鐘給你說個明明白白。以後再也不是事兒啦。