詳解字節流和字符流

一、明確字符和字節的概念

字節:1 byte = 8 bit
字符:1 char = 2 byte = 16 bit(java默認)

在計算機硬件層面,1 bit 是數據最小的單位。但是在大多數情況下,1 bit 存儲的信息太少,我們通常把 1 字節作為數據最小的基本單位。

而字符實際上也是對字節的一種包裝,那為什么還需要引入字符?
對于西方世界,使用英語等語種的國家來說,1字節有 256個符號編碼,對于26個英文字母加上常用的標點符號已經夠用了。這就是常用的ASCII 碼。
但是對于東方國家,中文,日文等文字,數量太多,1個字節根本沒有辦法表示所有的字符,所以引入了Unicode —— 統一編碼,而這種編碼的常規字符集就是使用2個字節,所以引入了字符的概念。

但是,從根本而言,一切都是字節流,字符流也是字節流的一種形式。

二、關于 java中字節流和字符流

2.1 字節流,字符流概念

Java中,讀取數據時,字節流的數據存儲單位是字節,會使用字節類型數組 byte[] 來保存數據,可以操作字節,字節數組。
而 字符流的存儲單位是字符,使用字符類數組 char[] 來保存數據,可以操作字符,字符數組或字符串。

2.2 java中的字節流,字符流相關API

Java 的I/O庫有兩個分支:

  • 面向字節流的InputSteam和OutputStream
  • 面向字符的Reader 和 wirter
InputStream

ByteArrayInputStream:把內存中的一個緩沖區作為 InputStream 使用 .
StringBufferInputStream: 把一個 String 對象作為 InputStream .
FileInputStream:把一個文件作為 InputStream ,實現對文件的讀取操作
PipedInputStream :實現了 pipe 的概念,主要在線程中使用 . 管道輸入流是指一個通訊管道的接收端。
一個線程通過管道輸出流發送數據,而另一個線程通過管道輸入流讀取數據,這樣可實現兩個線程間的通訊。
SequenceInputStream :把多個 InputStream 合并為一個 InputStream . “序列輸入流”類允許應用程序把幾個輸入流連續地合并起來,
并且使它們像單個輸入流一樣出現。每個輸入流依次被讀取,直到到達該流的末尾。

OutputStream

ByteArrayOutputStream : 把信息存入內存中的一個緩沖區中 . 該類實現一個以字節數組形式寫入數據的輸出流。
FileOutputStream: 文件輸出流是向 File 或 FileDescriptor 輸出數據的一個輸出流。
PipedOutputStream: 管道輸出流是指一個通訊管道的發送端。 一個線程通過管道輸出流發送數據,
而另一個線程通過管道輸入流讀取數據,這樣可實現兩個線程間的通訊。

Reader

CharArrayReader :與 ByteArrayInputStream 對應此類實現一個可用作字符輸入流的字符緩沖區
StringReader : 與 StringBufferInputStream 對應其源為一個字符串的字符流。
FileReader : 與 FileInputStream 對應
PipedReader :與 PipedInputStream 對應

Writer

CharArrayWrite : 與 ByteArrayOutputStream 對應
StringWrite :無與之對應的以字節為導向的 stream
FileWrite : 與 FileOutputStream 對應
PipedWrite :與 PipedOutputStream 對應

2.3 字符流,字節流API的使用

字節流示例

//字節流寫文件
public static void writeFile(){
    String str = "采用數據流方式(字節流)寫文件!";
    try{
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D://hello.txt",true));
        //需要轉化為字節
        byte[] data = str.getBytes();
        bos.write(data);
        bos.close();
    }catch (FileNotFoundException e){
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
//字節流讀文件
public static void readFile(){
    try {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D://hello.txt"));
        byte[] data = new byte[1024];
        int n = -1;
        while((n=bis.read(data,0,data.length))!=-1){
            String str = new String(data,0,n,"UTF-8");
            System.out.println(str);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

字符流示例

//字符流寫文件
public static void writeFile(){
    File file = new File("D:\\hello.txt");
    String str = " hello, everybody! welcome to the study of Java!";
    try{
        FileWriter fw = new FileWriter(file);
        BufferedWriter bw = new BufferedWriter(fw);
        bw.write(str);
        bw.close();
        fw.close();
    }catch(IOException e){
        e.printStackTrace();
    }
}
//字符流讀文件
public static void readerFile(){
    File file = new File("D:\\hello.txt");
    try{
        BufferedReader br = new BufferedReader(new FileReader(file));

        String str = null;
        while( (str = br.readLine()) != null){
            System.out.println(str);
        }
        br.close();
    }catch(FileNotFoundException e){
        e.printStackTrace();
    }catch(IOException e){
        e.printStackTrace();
    }
}

三、字節流和字符流的區別

字節流和字符流的區別:

  • 字節流在操作文件時,本身不會用到緩沖區(內存),是對文件本身直接操作的;而字符流在操作時是使用到緩沖區的。
  • 字節流在操作文件時,即使不關閉資源(close)文件也能輸出;字符流如果不是用close方法的話,則不會輸出任何內容,說明字符流使用了緩沖區。且可以使用flush方法強制進行刷新緩沖區,此時在不close情況下也能輸出內容。
  • Reader類的read()方法返回類型是int,占兩個字節,如果到達流的末尾,則返回-1;inputStream的read()方法雖然也返回int,打算面向字節流,占一個字節。因此對于超過一個字節的只能使用字符流來讀取,如漢字。
  • 處理方式不同;字節流:處理字節和字節數組成的二進制對象。
    字符流:處理字符,字符數或字符串。

注:緩沖區是什么??
緩沖區可以理解為一段特殊的內存。
在某些情況下,如果程序頻繁操作一個資源,則性能會很低,為了提升性能,可以將這部分數據暫時讀入內存的一塊區域,之后就可以直接從內存中讀取數據,提升速度和性能。

四、使用場景判斷

4.1 數據格式

  • 二進制格式(不能確定是純文本):字節流,InputStream、OutputStream及其子類。
  • 純文本格式(含中英文或其他編碼方式):字符流,Reader,Writer及其子類。

4.2 數據來源

  • 文件:字節流 FileInputStream,FileOutputStream;字符流 FileReader,FileWriter
  • byte[]: 字節流 ByteArrayInputStream, ByteArrayOutputStream char[]:字符流
  • CharArrayReader, CharArrayWriter String: 字節
  • StringBufferInputStream, StringBufferOuputStream ;字符流 StringReader,StringWriter
  • 網絡數據流:字節流 InputStream, OutputStream;字符流 Reader, Writer

4.3 是否需要格式化輸出

需要格式化輸出的:PrintStream, PrintWriter

4.4 是否需要緩沖

需要緩沖:字節流 BufferedInputStream, BufferedOutputStream;字符流 BufferedReader, BufferedWriter

4.5 輸入還是輸出

  • 輸入:Reader, InputStream 類型的子類
  • 輸出:Writer, OutputStream 類型的子類

4.6 是否有流轉化

  • 字節到字符:InputStreamReader
  • 字符到字節:OutputStreamWriter

4.7 特殊需要

  • 對象輸入輸出:ObjectInputStream, ObjectOutputStream
  • 進程間通信:PipedInputStream, PipedOutputStream, PipedReader, PipedWriter
  • 合并輸入: SequenceInputStream
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,533評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,055評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,365評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,561評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,346評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,889評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,978評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,118評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,637評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,558評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,739評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,246評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,980評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,619評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,347評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,702評論 2 370