教育行業(yè)A股IPO第一股(股票代碼 003032)

全國咨詢/投訴熱線:400-618-4000

深入理解字符流的編碼

更新時間:2018年12月19日14時59分 來源:傳智播客 瀏覽次數(shù):

Java中是以流的形式來實(shí)現(xiàn)數(shù)據(jù)在網(wǎng)絡(luò)中的傳輸,而所說的“流”則是字節(jié)流。因?yàn)樗械臄?shù)據(jù)的最底層都是以字節(jié)為單位存儲的,所以以字節(jié)為單位傳輸數(shù)據(jù)無疑是最簡單也是最有效的傳輸方式。
       我們在學(xué)習(xí)Java的過程中,也經(jīng)常接觸字符流,字符流顧名思義則是以字符為單位進(jìn)行數(shù)據(jù)傳輸,但是其實(shí)字符流的應(yīng)用面是很窄的,并不是所有的文件都存在字符的概念的,比如視頻文件、音頻文件、圖片文件,這些是無法以字符為單位進(jìn)行傳輸?shù)?。字符流只能對文本字符進(jìn)行操作。
       提到字符,我們首先就會想到的是編碼,因?yàn)橛嬎銠C(jī)存儲的是字節(jié),我們看到的卻是字符,這之間是靠編碼表對應(yīng)起來的,那么這也就是本篇文章索要研究的內(nèi)容—字符流編碼。
       首先我們來看下面的案例:
       案例顯示,Demo.java的項(xiàng)目編碼和b.txt的編碼格式一樣,則能夠正常寫入,不會亂碼。原理如下圖所示:
        字符流,每一個字符流都存在一個緩沖區(qū),緩沖區(qū)的編碼格式是和項(xiàng)目的編碼格式一致的,上述代碼執(zhí)行流程是:字符串“黑馬”在FileWriter的緩沖區(qū)里面通過GBK編碼把漢字編碼成對應(yīng)的字節(jié),然后底層通過字節(jié)流將字節(jié)寫入到b.txt。 很多人我們打開b.txt時看到的是“黑馬”這兩個字啊,并不是什么碼值啊。其實(shí)所有文件的底層都是字節(jié),子不過我們打開b.txt時,記事本軟件就通過此文件的編碼—GBK幫我們把碼值解碼成“黑馬”這兩個字了,所以我們看到的是黑馬。照這樣看來,如果b.txt的文件編碼是UTF-8的話,肯定就會亂碼,因?yàn)橛浭卤緯凑誙TF-8進(jìn)行解碼,效果如下圖所示:
        接下來難點(diǎn)才真正的來臨(很多人看了下面的代碼和運(yùn)行效果就蒙圈),我們把上圖的代碼改下(其他編碼格式不變),你會發(fā)現(xiàn)不亂碼了,如下圖:源碼如下:
[Java] 純文本查看 復(fù)制代碼
01
02
03
04
05
06
07
08
09
10
public class Demo {[/align]
        public static void main(String[] args) throws IOException {
                FileWriter fw = new FileWriter("b.txt");
                String s = "黑馬";
                byte[] bytes = s.getBytes("UTF-8");
                String s1 = new String(bytes);
                fw.write(s1);
                fw.close();
        }
}
      很多人蒙圈的原因是因?yàn)椋劝炎址D(zhuǎn)為了UTF-8 但是又通過new String(bytes)轉(zhuǎn)成了GBK啊,但是b.txt是UTF-8格式的編碼啊。為什么沒有亂碼呢? 下圖解釋的很詳細(xì):
       執(zhí)行流程是:先通過UTF-8編碼把“黑馬”編碼成幾個字節(jié)比如13 42 35 86 59 47,然后再通過GBK編碼,把該碼值解碼成對應(yīng)的字符比如“傳智人”,然后“傳智人”進(jìn)入緩沖區(qū)會通過GBK編碼編碼成剛才的字節(jié) 也就是13 42 35 86 59 47,然后再通過字節(jié)流寫入到b.txt中,當(dāng)打開b.txt時,記事本軟件會按照此文件編碼格式-UTF-8解碼成“黑馬”,所以我們看到的是沒有亂碼。

       總結(jié):通過比價復(fù)雜的案例我們明白了一、每個字符流都存在緩沖區(qū),而且緩沖區(qū)的編碼是和項(xiàng)目編碼一致。二、字符流的底層依然是使用的字節(jié)流,而且還存在緩沖區(qū)的編碼動作,所以效率比字節(jié)流會慢很多,所以通常數(shù)據(jù)的傳輸我們都會使用字節(jié)流。三、文本文件的底層存儲的也是字節(jié),我們打開文件看到的字符,是記事本軟件所做的解碼。



作者:傳智播客JavaEE培訓(xùn)學(xué)院

首發(fā):http://java.itcast.cn

0 分享到:
和我們在線交談!