深刻理解JAVA I/O系列三:字符流詳解

深刻理解JAVA I/O系列三:字符流詳解

字符流爲什麼存在

既然字節流提供了可以處理任何類型的輸入/輸出操做的功能,那爲何還要存在字符流呢?容我慢慢道來,字節流不能直接操做Unicode字符,由於一個字符有兩個字節,字節流一次只能操做一個字節。若是JAVA不能直接操做字符,我會感到JAVA對這個世界滿滿的惡意,因此提供對直接的字符輸入/輸出的支持是頗有必要的,由於咱們的口號是:一次編寫,處處運行。html

字符流的概念

輸出字符流:把要寫入文件的字符序列(實際是unicode碼元序列)轉爲指定編碼方式下的字節序列,而後在寫入文件中。java

輸入字符流:把要讀取的字節序列按照指定編碼方式轉爲相應的字符序列(實際是unicode碼元序列),從而寫入內存中。編碼

字符流的層次關係

字符流層次結構的頂層是Reader和Writer抽象類,與字節流中的InputStream、OutputStream相對應。spa

 

 下面實現這樣一個功能:將字符串寫入一個文件,而後再從文件中讀取在控制檯打印,經過這個DEMO來熟悉字符流家族中的一些經常使用流。code

首先將字符串寫入文件:視頻

複製代碼
public static void main(String[] args) throws IOException
    {
        FileOutputStream fis = new FileOutputStream("d:/data.txt");
        OutputStreamWriter osw = new OutputStreamWriter(fis);
        BufferedWriter bw = new BufferedWriter(osw);
        String str1 = "中國移動閱讀基地";
        String str2 = "中國移動視頻基地";
        bw.write(str1);
        bw.write("\r\n");
        bw.write(str2);
        
        bw.close();
    }
複製代碼

執行結果: htm

再從文件中讀取打印在控制檯blog

複製代碼
1         FileOutputStream fos = new FileOutputStream("d:/data.txt");
 2         OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
 3         BufferedWriter bw = new BufferedWriter(osw);
 4         String str1 = "中國移動閱讀基地";
 5         String str2 = "中國移動視頻基地";
 6         bw.write(str1);
 7         bw.write("\r\n");
 8         bw.write(str2);
 9         
10         bw.close();
11         
12         FileInputStream fis = new FileInputStream("d:/data.txt");
13         InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
14         BufferedReader br = new BufferedReader(isr);
15         String str;
16         while(null != (str = br.readLine()))
17         {
18             System.out.println(str);
19         }
20         br.close();
21
複製代碼

執行結果:內存

中國移動閱讀基地
中國移動視頻基地

一、這裏面的BufferedWriter、BufferedReader與字節流中的BufferedInputStream、BufferedOutputStream相對應,功能原理相似,不作展開介紹。utf-8

二、第2行、第13行代碼的做用分別是將字節輸出流、字節輸入流經過制定的編碼方式,轉換成了字符輸出流、字符輸入流。

OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
InputStreamReader isr = new InputStreamReader(fis,"UTF-8");

OutputStreamWriter、InputStreamReader就是輸入/輸出體系中提供的兩個轉換流,用於實現將字節流轉換成字符流。

你們能夠思考這樣一個問題:爲何沒有把字符流轉換成字節流的轉換流呢?

首先想一字節流和字符流的區別:字節流比字符流的使用範圍更廣,但字符流比字節流操做方便。若是一個流已是字符流,也就意味着這是一個使用起來更方便的流,爲何還要轉換成字節流呢?反之,若是如今有一個字節流,但能夠肯定這個字節流的內容都是文本內容,咱們就能夠將它轉換成字符流處理起來會更方便一點。因此,java只提供了字節流到字符流的轉換,沒有提供字符流到字節流的轉換。

 

上面的DEMO是經過字節到字符的轉換流來實現的,下面咱們來看看是否能夠經過直接讀取文本中的字符來實現:

複製代碼
1 public static void main(String[] args) throws IOException
 2     {
 3         FileWriter fw = new FileWriter("d:data.txt");
 4         BufferedWriter bw = new BufferedWriter(fw);
 5         String str1 = "中國移動閱讀基地";
 6         String str2 = "中國移動視頻基地";
 7         bw.write(str1);
 8         bw.write("\r\n");
 9         bw.write(str2);
10         bw.close();
11         
12         FileReader fr = new FileReader("d:data.txt");
13         BufferedReader br = new BufferedReader(fr);
14         String str;
15         while(null != (str = br.readLine()))
16         {
17             System.out.println(str);
18         }
19         br.close();
20         
21     }
複製代碼

執行結果:

中國移動閱讀基地
中國移動視頻基地

咱們能夠看到,這裏能夠經過FileWriter/FileReader來直接操做文本文件。

一、使用FileReader或BufferedReader從文件中讀取字符或文本數據,並老是指定字符編碼;使用FileInputStream從Java中文件或套接字中讀取原始字節流。

二、因爲BufferedReader具備一個readLine方法,能夠很是方便地一次讀入一行內容,因此常常把讀取文件內容的輸入流包裝成BufferedReader,用來方便地讀取輸入流的文本內容。

知識點TIPS

計算機的文件常被分紅文本文件和二進制文件兩大類:

一、咱們不妨能夠這樣絕對的認爲:全部能用記事本打開而且看到其中字符內容文件稱爲文本文件,反之則是二進制文件。

二、其實計算機中全部的文件都是二進制文件,文本文只是二進制文件中的一個特殊的存在。若是二進制文件的內容剛好能被正常解析成字符時,則該二進制文件就能夠稱之爲文本文件。

三、在有些狀況下,文本文件使用了錯誤的字符集打開,也會生成亂碼。因此若是向正常使用文本文件,必須在打開文件時使用與保存文件是相同的字符集。

相關文章
相關標籤/搜索