日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[转载] 菜鸟举例理解字节流和字符流区别

發(fā)布時間:2025/3/11 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [转载] 菜鸟举例理解字节流和字符流区别 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

參考鏈接: Java中的字符流與字節(jié)流 Character Stream對比Byte Stream

菜鳥舉例理解字節(jié)流和字符流區(qū)別?

?按照uft8編碼方式存儲文檔?

?文檔存儲路徑在D盤下?

/**

* 按照utf8格式存儲文檔

*/

public static void storeDataByUTF8(){

? ? String path = "D:" + File.separator + "textutf8.txt";

? ? File file = new File(path);

? ? try {

? ? ? ? PrintWriter pw = new PrintWriter(file,"utf-8");

? ? ? ? for(int i=0;i<5;i++){

? ? ? ? ? ? pw.write(i+":"+"字節(jié)流與字符流!!!"+"\r\n");

? ? ? ? }

? ? ? ? pw.flush();

? ? ? ? pw.close();

? ? } catch (FileNotFoundException | UnsupportedEncodingException e) {

? ? ? ? e.printStackTrace();

? ? }

}?

?對比使用BufferedReader和FileInputStream按照byte讀取文檔(按照字節(jié)流方式讀取)?

?使用BufferedReader按照byte讀取文檔代碼如下:?

public static void readDataWithArray(){

? ? String path = "D:" + File.separator + "textutf8.txt";

? ? File file = new File(path);

? ? try{

? ? ? ? FileInputStream fis = new FileInputStream(file);

? ? ? ? ? InputStreamReader isr = new InputStreamReader(fis,"utf-8");

? ? ? ? BufferedReader in = new BufferedReader(isr);

? ? ? ? byte[] b = new byte[2048];

? ? ? ? int temp = 0;

? ? ? ? int len = 0;

? ??????

? ? ? ? while((temp=in.read())!=-1){? // -1是結(jié)束符

? ? ? ? ? ? b[len] = (byte)temp;

? ? ? ? ? ? if(len<2047)

? ? ? ? ? ? ? ? len++;

? ? ? ? ? ? else

? ? ? ? ? ? ? ? break;

? ? ? ? }

? ? ? ? in.close();

? ? ? ? System.out.println(new String(b,0,len,"utf-8"));

? ??????

? ? }catch(Exception e){

? ? ? ? e.printStackTrace();

? ? ? ? System.out.println("While reading the data, the program threw out exceptions");

? ? }

?

}?

?輸出結(jié)果發(fā)生了亂碼:?

0:W?AW&A

1:W?AW&A

2:W?AW&A

3:W?AW&A

4:W?AW&A?

?FileInputStream按照byte讀取文檔代碼如下:?

public static void readDataWithArray(){

? ? String path = "D:" + File.separator + "textutf8.txt";

? ? File file = new File(path);

? ? try{

? ? ? ? FileInputStream in = new FileInputStream(file);

? ? ? ? //InputStreamReader isr = new InputStreamReader(fis,"utf-8");

? ? ? ? //BufferedReader in = new BufferedReader(isr);

? ??????

? ? ? ? byte[] b = new byte[2048];

? ? ? ? int temp = 0;

? ? ? ? int len = 0;

? ??????

? ? ? ? while((temp=in.read())!=-1){? // -1是結(jié)束符

? ? ? ? ? ? b[len] = (byte)temp;

? ? ? ? ? ? if(len<2047)

? ? ? ? ? ? ? ? len++;

? ? ? ? ? ? else

? ? ? ? ? ? ? ? break;

? ? ? ? }

? ? ? ? in.close();

? ? ? ? System.out.println(new String(b,0,len,"utf-8"));

? ??????

? ? }catch(Exception e){

? ? ? ? e.printStackTrace();

? ? ? ? System.out.println("While reading the data, the program threw out exceptions");

? ? }

?

}?

?輸出結(jié)果正常:?

0:字節(jié)流與字符流!!!

1:字節(jié)流與字符流!!!

2:字節(jié)流與字符流!!!

3:字節(jié)流與字符流!!!

4:字節(jié)流與字符流!!!?

?以上兩段代碼不同之處只是讀取文本的流不同,其他代碼相同。要回答這個問題,首先來理解一下為什么要編碼??

?為什么要編碼?

?不知道大家有沒有想過一個問題,那就是為什么要編碼?我們能不能不編碼?要回答這個問題必須要回到計算機是如何表示我們?nèi)祟惸軌蚶斫獾姆柕?#xff0c;這些符號也就是我們?nèi)祟愂褂玫恼Z言。由于人類的語言有太多,因而表示這些語言的符號太多,無法用計算機中一個基本的存儲單元—— byte 來表示,因而必須要經(jīng)過拆分或一些翻譯工作,才能讓計算機能理解。我們可以把計算機能夠理解的語言假定為英語,其它語言要能夠在計算機中使用必須經(jīng)過一次翻譯,把它翻譯成英語。這個翻譯的過程就是編碼。所以可以想象只要不是說英語的國家要能夠使用計算機就必須要經(jīng)過編碼。 所以總的來說,編碼的原因可以總結(jié)為:?

計算機中存儲信息的最小單元是一個字節(jié)即 8 個 bit,所以能表示的字符范圍是 0~255 個人類要表示的符號太多,無法用一個字節(jié)來完全表示要解決這個矛盾必須需要一個新的數(shù)據(jù)結(jié)構(gòu) char,從 char 到 byte 必須編碼?

?為什么兩者的結(jié)果那么不同呢??

?在Java中byte是1個字節(jié)(8個bit),char是2個字節(jié); 最基礎(chǔ)的流InputStream和OutputStream是按照字節(jié)讀取的(byte)。?

/**

?* Reads a byte of data from this input stream. This method blocks

?* if no input is yet available.

?*

?* @return? ? ?the next byte of data, or <code>-1</code> if the end of the

?*? ? ? ? ? ? ?file is reached.

?* @exception? IOException? if an I/O error occurs.

?*/

public int read() throws IOException {

? ? return read0();

}?

?但是BufferedReader類的read()方法返回的是char。所以沒有處理好編碼原因的第三個原因。?

public class BufferedReader extends Reader {

? ? private char cb[];? // char數(shù)組的緩存

? ? private int nChars, nextChar;

? ? ...

? ? ? ? /**

? ? ?* Reads a single character.

? ? ?*

? ? ?* @return The character read, as an integer in the range

? ? ?*? ? ? ? ?0 to 65535 (<tt>0x00-0xffff</tt>), or -1 if the

? ? ?*? ? ? ? ?end of the stream has been reached

? ? ?* @exception? IOException? If an I/O error occurs

? ? ?*/

? ? public int read() throws IOException {

? ? ? ? synchronized (lock) {

? ? ? ? ? ? ensureOpen();

? ? ? ? ? ? for (;;) {

? ? ? ? ? ? ? ? if (nextChar >= nChars) {

? ? ? ? ? ? ? ? ? ? fill();

? ? ? ? ? ? ? ? ? ? if (nextChar >= nChars)

? ? ? ? ? ? ? ? ? ? ? ? return -1;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if (skipLF) {

? ? ? ? ? ? ? ? ? ? skipLF = false;

? ? ? ? ? ? ? ? ? ? if (cb[nextChar] == '\n') {

? ? ? ? ? ? ? ? ? ? ? ? nextChar++;

? ? ? ? ? ? ? ? ? ? ? ? continue;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? return cb[nextChar++];

? ? ? ? ? ? }

? ? ? ? }

? ? }

? ??

}?

?舉個詳細的例子: 按照 ISO-8859-1 編碼字符串“I am 君山”用 ISO-8859-1 編碼,下面是編碼結(jié)果:??

?從上圖看出7個char 字符經(jīng)過ISO-8859-1 編碼轉(zhuǎn)變成7個byte 數(shù)組,ISO-8859-1是單字節(jié)編碼,中文“君山”被轉(zhuǎn)化成值是3f的byte。3f也就是“?”字符,所以經(jīng)常會出現(xiàn)中文變成“?”很可能就是錯誤的使用了 ISO-8859-1這個編碼導(dǎo)致的。中文字符經(jīng)過 ISO-8859-1編碼會丟失信息,通常我們稱之為“黑洞”,它會把不認識的字符吸收掉。由于現(xiàn)在大部分基礎(chǔ)的 Java 框架或系統(tǒng)默認的字符集編碼都是 ISO-8859-1,所以很容易出現(xiàn)亂碼問題。?

?以上總結(jié)只是舉例了一個簡單的例子,希望能通過這個例子使得你對Java字節(jié)流和字符流的區(qū)別有個感性的認識。如果需要了解兩者的區(qū)別,強烈建議大家看看另一篇博客《深入分析 Java 中的中文編碼問題》。?

?如果博客寫得有什么問題,請各請各位大神指出。

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的[转载] 菜鸟举例理解字节流和字符流区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。