22 Java學習之字元流(Reader和Writer)
Java中的流是個抽象的概念,當程式需要從某個資料來源讀入資料的時候,就會開啟一個數據流,資料來源可以是檔案、記憶體或網路等等。相反地,需要寫出資料到某個資料來源目的地的時候,也會開啟一個數據流,這個資料來源目的地也可以是檔案、記憶體或網路等等
一. 字元流的引入
正如位元組流中所看到的,有時候當一箇中文字元含有兩個位元組時,位元組流它時一次只能操作一個位元組,它不能直接操作Unicode字元。因此引入了字元流。
二. 字元流
字元流分為輸入字元流和輸出字元流。它們的基類代表分別時Reader和Writer。
Writer: 把要寫入檔案的字元序列(實際上是unicode碼元序列)轉為指定編碼方式下的位元組序列,然後再寫入檔案中。
Reader:把要讀取的位元組序列按照指定編碼方式轉為相應的字元序列(實際上是unicode碼元序列),從而寫入記憶體中。
三. 字元輸入流
1. 常見的字元輸入流有:
- Reader
- InputStreamReader
- FileReader
- BufferedReader
2. 它們的用途與區別
(1)Reader:是字元流的抽象基類,它包含了重要方法有read和close
(2)InputStreamReader:可以把InputStream中的位元組資料流根據字元編碼方式轉換成字元資料流。
(3)FileReader:可以把FileInputStream中的位元組資料轉換成根據字元編碼方式轉成字元數字流。
(4)BufferedReader:可以把字元輸入流進行封裝,將資料進行緩衝,提高讀取效率。它含有read(末尾返回-1)和readLine()(末尾返回Null).
3. InputStreamReader的使用
1 package com.test.a; 2 3 import java.io.FileInputStream; 4 import java.io.IOException; 5 import java.io.InputStreamReader; 6 7 public class Test { 8 public staticView Codevoid main(String args[]) throws IOException { 9 FileInputStream fileInputStream=new FileInputStream("C:\\Users\\hermioner\\Desktop\\test.txt"); 10 InputStreamReader inputStreamReader=new InputStreamReader(fileInputStream); 11 int ch; 12 while((ch=inputStreamReader.read())!=-1) 13 { 14 System.out.println((char)ch); 15 } 16 inputStreamReader.close(); 17 fileInputStream.close(); 18 } 19 } 20 21 我 22 愛 23 我 24 家
note:test.txt中的內容是橫著的 我愛我家
note:InputStreamReader需要一個位元組輸入流物件作為例項化引數。還可以指定第二個引數,第二個引數是字元編碼方式,可以是編碼方式的字串形式,也可以是一個字符集物件。
4. FileReader
1 package com.test.a; 2 3 import java.io.FileReader; 4 import java.io.IOException; 5 6 public class Test { 7 public static void main(String args[]) throws IOException { 8 FileReader reader=new FileReader("C:\\Users\\hermioner\\Desktop\\test.txt"); 9 char chars[]=new char[1024]; 10 int len; 11 while((len=reader.read(chars))!=-1) { 12 System.out.println(new String(chars,0,len)); 13 } 14 reader.close(); 15 } 16 } 17 18 我愛我家View Code
note:FileReader 需要一個檔案物件作為例項化引數,可以是File類物件,也可以是檔案的路徑字串。
5. BufferedReader
1 package com.test.a; 2 3 import java.io.BufferedReader; 4 import java.io.FileReader; 5 import java.io.IOException; 6 7 public class Test { 8 public static void main(String args[]) throws IOException { 9 FileReader fileReader=new FileReader("C:\\Users\\hermioner\\Desktop\\test.txt"); 10 BufferedReader bufferedReader=new BufferedReader(fileReader); 11 String line; 12 while((line=bufferedReader.readLine())!=null) { 13 System.out.println(line); 14 } 15 bufferedReader.close(); 16 fileReader.close(); 17 } 18 } 19 20 21 我愛我家View Code
note: BufferReader需要一個字元輸入流物件作為例項化引數。
四. 字元輸出流
1. 常見的字元輸出流有:
- Writer
- OutputStreamWriter
- FileWriter
- BufferedWriter
它們的區別和用途:
(1)Writer:是字元輸出流的抽象基類,它包含的重要方法有wirte、close、flush(重新整理輸出流,把資料馬上寫到輸出流中)
(2)OutputStreamWriter:可以使我們直接往流中寫字串資料,它裡面會幫我們根據字元編碼方式來把字元資料轉成位元組資料再寫給輸出流,它相當於一箇中介\橋樑。
(3)FileWriter:與OutputStreamWriter功能類似,我們可以直接往流中寫字串資料,FileWriter內部會根據字元編碼方式來把字元資料轉成位元組資料再寫給輸出流。
(4)BufferedWriter:比FileWriter還高階一點,它利用了緩衝區來提高寫的效率。它還多出了一個函式:
- newLine() :寫入一個換行符。
2. OutputStreamWriter使用
1 public class Test { 2 public static void main(String args[]) throws IOException { 3 OutputStream outputStream=new FileOutputStream("C:\\Users\\hermioner\\Desktop\\test.txt"); 4 OutputStreamWriter outputStreamWriter=new OutputStreamWriter(outputStream); 5 outputStreamWriter.write("hello world,你好"); 6 outputStreamWriter.close(); 7 } 8 } 9 10 11 就可以在test中寫入資料。View Code
說明:OutputStreamWriter是需要傳入一個流物件作為例項化引數的
3. FileWriter使用
1 public class Test { 2 public static void main(String args[]) throws IOException { 3 FileWriter fileWriter=new FileWriter("C:\\Users\\hermioner\\Desktop\\test.txt"); 4 fileWriter.write("加油"); 5 fileWriter.close(); 6 } 7 } 8 9 檔案中就寫入了字串內容View Code
說明:FileWriter需要一個檔案物件來例項化,可以是File類物件,也可以是檔案的路徑字串。
4. BufferedWriter使用
1 public class Test { 2 public static void main(String args[]) throws IOException{ 3 FileWriter fileWriter=new FileWriter("C:\\Users\\hermioner\\Desktop\\test.txt"); 4 BufferedWriter bufferedWriter=new BufferedWriter(fileWriter); 5 bufferedWriter.write("加油"); 6 bufferedWriter.close(); 7 fileWriter.close(); 8 } 9 }View Code
五.總結
1. OutputStreamWriter、InputStreamReader就是輸入、輸出提起中提供的兩個轉換流,用於將位元組流轉換為字元流。-------只能從位元組流轉換到字元流。
2.為什麼不能從字元流轉換到位元組流?
首先想一位元組流和字元流的區別:位元組流比字元流的使用範圍更廣,但字元流比位元組流操作方便。如果一個流已經是字元流,也就意味著這是一個使用起來更方便的流,為什麼還要轉換成位元組流呢?反之,如果現在有一個位元組流,但可以確定這個位元組流的內容都是文字內容,我們就可以將它轉換成字元流處理起來會更方便一點。所以,java只提供了位元組流到字元流的轉換,沒有提供字元流到位元組流的轉換。
3. 計算機中的檔案常被分成文字檔案和二進位制檔案兩大類:
- 我們不妨可以這樣絕對的認為:所有能用記事本開啟並且看到其中字元內容檔案稱為文字檔案,反之則是二進位制檔案。
- 其實計算機中所有的檔案都是二進位制檔案,文字文只是二進位制檔案中的一個特殊的存在。如果二進位制檔案的內容恰好能被正常解析成字元時,則該二進位制檔案就可以稱之為文字檔案。
- 在有些情況下,文字檔案使用了錯誤的字符集開啟,也會生成亂碼。所以如果想正常使用文字檔案,必須在開啟檔案時使用與儲存檔案是相同的字符集。
參考文獻:
https://www.cnblogs.com/progor/p/9357676.html
https://www.cnblogs.com/dongguacai/p/5676254.html