[轉載] 菜鳥舉例理解字節流和字符流區別

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

菜鳥舉例理解字節流和字符流區別?

?按照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+":"+"字節流與字符流!!!"+"\r\n");

? ? ? ? }

? ? ? ? pw.flush();

? ? ? ? pw.close();

? ? } catch (FileNotFoundException | UnsupportedEncodingException e) {

? ? ? ? e.printStackTrace();

? ? }

}?

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

?使用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是結束符

? ? ? ? ? ? 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");

? ? }

?

}?

?輸出結果發生了亂碼:?

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是結束符

? ? ? ? ? ? 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");

? ? }

?

}?

?輸出結果正常:?

0:字節流與字符流!!!

1:字節流與字符流!!!

2:字節流與字符流!!!

3:字節流與字符流!!!

4:字節流與字符流!!!?

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

?為什么要編碼?

?不知道大家有沒有想過一個問題,那就是為什么要編碼?我們能不能不編碼?要回答這個問題必須要回到計算機是如何表示我們人類能夠理解的符號的,這些符號也就是我們人類使用的語言。由于人類的語言有太多,因而表示這些語言的符號太多,無法用計算機中一個基本的存儲單元—— byte 來表示,因而必須要經過拆分或一些翻譯工作,才能讓計算機能理解。我們可以把計算機能夠理解的語言假定為英語,其它語言要能夠在計算機中使用必須經過一次翻譯,把它翻譯成英語。這個翻譯的過程就是編碼。所以可以想象只要不是說英語的國家要能夠使用計算機就必須要經過編碼。 所以總的來說,編碼的原因可以總結為:?

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

?為什么兩者的結果那么不同呢??

?在Java中byte是1個字節(8個bit),char是2個字節; 最基礎的流InputStream和OutputStream是按照字節讀取的(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數組的緩存

? ? 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 編碼,下面是編碼結果:??

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

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

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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/540241.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/540241.shtml
英文地址,請注明出處:http://en.pswp.cn/news/540241.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[轉載] Java9發布回顧Java 8的十大新特性

參考鏈接&#xff1a; Java中的DoubleStream mapToObj() java9已經在北京時間9月22日正式發布&#xff0c;開發者可以在oracle jdk官網上下載到最新的jdk9。 今天&#xff0c;我們先來一起復習一下2014年發布的Java 8的十大新特性。先來喝杯java~~~ 按照java升級的傳統&…

窗體間傳遞數據

前言 做項目的時候&#xff0c;winfrom因為沒有B/S的緩存機制&#xff0c;窗體間傳遞數據沒有B/S頁面傳遞數據那么方便&#xff0c;今天我們就說下winfrom中窗體傳值的幾種方式。 共有字段傳遞 共有字段傳遞實現起來很方便&#xff0c;就是在窗體類中加個共有字段屬性&#xff…

[轉載] c語言中檢查命令行參數_C中的命令行參數

參考鏈接&#xff1a; Java中的命令行參數 c語言中檢查命令行參數 Command line argument is a parameter supplied to the program when it is invoked. Command line argument is an important concept in C programming. It is mostly used when you need to control your …

MySQL關閉Enterprise Server源碼

今天從MySQL官方網站上獲知&#xff0c;MySQL宣布關閉Enterprise Server的源碼&#xff0c;對于廣大開源愛好者來說&#xff0c;這是一個沉重的打擊。雖然免費的用戶群體一般僅僅使用MySQL Community Server&#xff08;開源免費社區版&#xff09;&#xff0c;但關閉MySQL Ent…

[轉載] Java中Scanner用法總結

參考鏈接&#xff1a; Java之Scanner類 最近在做OJ類問題的時候&#xff0c;經常由于Scanner的使用造成一些細節問題導致程序不通過&#xff08;最慘的就是網易筆試&#xff0c;由于sc死循環了也沒發現&#xff0c;導致AC代碼也不能通過。。。&#xff09;&#xff0c;因此對S…

os和shutil模塊

import os //os模塊基本實現了linux系統中所有的命令 os.system(終端命令)&#xff1a;在終端執行命令 os.getcwd():獲取當前的工作路徑 os.chdir():修改工作路徑 os.chmod():修改權限 os.chown():修改屬主屬組 os.mkdir():創建單個目錄&#xff0c;當目錄存在時報異常&…

[轉載] JAVA語言程序設計(基礎篇)第十版課后題答案(第一章)

參考鏈接&#xff1a; Java中的Scanner和nextChar() JAVA語言程序設計&#xff08;基礎篇&#xff09;第十版課后題答案 第一章 第二題 /** Created by ysy on 2018/7/6. */ public class text2 { public static void main(String[] args){ for(int i 0; i < 5; i) Syste…

java.util.Date和java.sql.Date 一點區別

最近無意中發現&#xff0c;在oracle中同一樣的一個Date類型字段&#xff0c;存儲的日期格式有兩種不同的情況&#xff0c;第一種是2011-1-1 12:00:00&#xff0c;第二種是2011-1-1&#xff0c;仔細查找發現在向數據庫中寫數據的時候定義的變量的問題。 第一種是&#xff1a;ja…

[轉載] java中關于用\t格式輸出

參考鏈接&#xff1a; 用Java格式化輸出 看了好多人關于\t的用法&#xff0c;感覺找不到自己想要的答案&#xff0c;所以索性就自己輸出來看看&#xff0c;如圖&#xff1a;這樣可以一目了然的看出來&#xff0c;\t&#xff08;制表符&#xff09;的作用就是看前面輸出滿不滿8…

微信搶房軟件開發

2019獨角獸企業重金招聘Python工程師標準>>> 這兩年樓市真可謂是一個"火“字難以形容 經歷了長沙兩次開盤&#xff0c;都沒有搶到&#xff0c;目前還沒有買到房子&#xff0c;說說我的悲劇吧&#xff0c;讓大伙都開心開心 第一次搶房是今年4月份長沙萬科金域國…

[轉載] Java——數組習題

參考鏈接&#xff1a; Java從控制臺讀取輸入的方法 package chap02; import java.util.Scanner; /** * * author admin * date 2020-4-8 * description: * 題目內容&#xff1a; 編寫程序&#xff0c; 從控制臺讀取下面的信息&#xff0c; 每月按22天工作日計算&#xff0c;…

超全Linux備份工具集合,滿足你的所有需要!

經常備份計算機上的數據是個好的做法&#xff0c;它可以手動完成&#xff0c;也可以設置成自動執行。許多備份工具擁有不同的功能特性&#xff0c;讓用戶可以配置備份類型、備份時間、備份對象、將備份活動記入日志及執行更多操作。 1.Rsync這是一款在Linux用戶當中頗受歡迎的命…

[轉載] Java內存管理-你真的理解Java中的數據類型嗎(十)

參考鏈接&#xff1a; Java中的字符串類String 1 做一個積極的人 編碼、改bug、提升自己 我有一個樂園&#xff0c;面向編程&#xff0c;春暖花開&#xff01; 推薦閱讀 第一季 0、Java的線程安全、單例模式、JVM內存結構等知識梳理 1、Java內存管理-程序運行過程&#x…

Linux系統安全加固腳本

閑來無事&#xff0c;整理一個系統安全加固腳本&#xff0c;每個公司的要求不一樣&#xff0c;所以僅供參考&#xff1a; #!/bin/sh echo "00 */1 * * * /usr/sbin/ntpdate 192.168.1.1 >>/var/log/ntpdate.log" > mycrontab crontab mycrontab rm -rf my…

[轉載] 整理下java中stringBuilder和stringBuffer兩個類的區別

參考鏈接&#xff1a; Java中的StringBuffer類 StringBuilder和StringBuffer這兩個類在動態拼接字符串時常用&#xff0c;肯定比String的效率和開銷小&#xff0c;這是因為String的對象不會回收哦。 其實我一直用StringBuilder這個類&#xff0c;因為可以簡寫為sb的變量在程序…

11.13 模10計數器設計

.新建一個工程 Family&#xff1a;FLEX10K Available device&#xff1a;EPF10K20TC144-3 2.設置lpm_counter宏單元參數并連接引腳 連接引腳的時候要注意的是&#xff0c;向量線的連接。 3.時序仿真 檢查無誤后進行下一步 4.載入7448并進行引腳連接 5.分配管腳 再次編譯&#x…

[轉載] java對象在內存中的結構

參考鏈接&#xff1a; 了解Java中的類和對象 今天看到一個不錯的PPT&#xff1a;Build Memory-efficient Java Applications&#xff0c;開篇便提出了一個問題&#xff0c;在Hotspot JVM中&#xff0c;32位機器下&#xff0c;Integer對象的大小是int的幾倍&#xff1f; 我們…

使用valueOf前必須進行校驗

每個枚舉都是java.lang.Enum的子類,都可以訪問Enum類提供的方法,比如hashCode(),name(),valueOf()等..... 其中valueOf()方法會把一個String類型的名稱轉變為枚舉項,也就是枚舉項中查找出字面值與該參數相等的枚舉項,雖然這個方法很簡單,但是JDK卻做了一個對于開發人員來說并不…

[轉載] 【Java】Java基礎知識及其擴展筆記(8千字)

參考鏈接&#xff1a; Java中的StringBuilder類及其示例 Java基礎知識及其擴展筆記 零 l 寫在前面一 l JVM1、【1.1.2.1】java程序運行的一般流程2、【1.1.2.1】JVM一般運行流程3、【1.1.2.1】JIT&#xff08;just in time 即時編譯編譯器&#xff09;4、堆與棧 二 l Java …

多IDC GSLB的部署

之前已經介紹過GSLB的實現原理&#xff0c;這里再向大家講述一下GSLB經常遇到的部署方式&#xff0c;多IDC的部署。很多大型的企業或業務容災要求非常高的客戶都會部署有多個異地的數據中心&#xff0c;以保證其業務的“全天候”不間斷的正常運行&#xff0c;而要整合多個IDC的…