一、BufferedReader類
. 所屬類庫:
java.lang.Object
java.io.Reader
java.io.BufferedReader
. 基本概念:
public class BufferedReader extends Reader
從字符輸入流中讀取文本,緩衝各個字符,從而實現字符、數組和行的高效讀取。 可以指定緩衝區的大小,或者可使用默認的大小。大多數情況下,默認值足夠大。
通常, Reader 所作的每個讀取請求都會導致對底層字符或字節流進行相應的讀取請求。因此,建議用BufferedReader 包裝所有其read() 操作可能開銷很高的Reader (如FileReader 和InputStreamReader )。
BufferedReader 流能夠讀取文本行, 通過向BufferedReader 傳遞一個Reader 對象, 來創建一個BufferedReader 對象, 之所以這樣做是因為FileReader 沒有提供讀取文本行的功能.
. Demo :
通過Bufferedreader 捕獲所輸入的語句:
import java.io.*;class BufferedReaderDemo{ public static void main(String[] args)throws IOException { BufferedReader bufferedReader =new BufferedReader( new InputStreamReader(System.in)); System.out.print("請輸入一系列文字,可包括空格:"); String text =bufferedReader.readLine(); System.out.println("請輸入文字:"+text); } }註解:
throws IOException 拋出異常
InputStreamReader 是字節流通向字符流的橋樑
二、InputStreamReader類
InputStreamReader 將字節流轉換為字符流。是字節流通向字符流的橋樑。如果不指定字符集編碼,該解碼過程將使用平台默認的字符編碼,如:GBK。
構造方法:
InputStreamReader isr = new InputStreamReader(InputStream in);//構造一個默認編碼集的InputStreamReader類
InputStreamReader isr = new InputStreamReader(InputStream in,String charsetName);//構造一個指定編碼集的
InputStreamReader類。
參數in對象通過InputStream in = System.in;獲得。 //讀取鍵盤上的數據。
或者InputStream in = new FileInputStream(String fileName);//讀取文件中的數據。可以看出FileInputStream 為InputStream的子類。
主要方法:int read();//讀取單個字符。
int read(char []cbuf);//將讀取到的字符存到數組中。返回讀取的字符數。
. Demo :
import java.io.*;class InputStreamReaderDemo { public static void transReadNoBuf() throws IOException { /** * 沒有緩衝區,只能使用read()方法。 */ //讀取字節流//InputStream in = System.in;//讀取鍵盤的輸入。 InputStream in = new FileInputStream("D://demo.txt");//讀取文件的數據。 //將字節流向字符流的轉換。要啟用從字節到字符的有效轉換, //可以提前從底層流讀取更多的字節. InputStreamReader isr = new InputStreamReader(in);//讀取//綜合到一句。 //InputStreamReader isr = new InputStreamReader( //new FileInputStream("D://demo.txt")); char []cha = new char[1024]; int len = isr.read(cha); System.out.println(new String(cha,0,len)); isr.close(); } public static void transReadByBuf() throws IOException { /** * 使用緩衝區可以使用緩衝區對象的read() 和readLine()方法。 */ //讀取字節流//InputStream in = System.in;//讀取鍵盤上的數據InputStream in = new FileInputStream("D://demo.txt");//讀取文件上的數據。 //將字節流向字符流的轉換。 InputStreamReader isr = new InputStreamReader(in);//讀取//創建字符流緩衝區BufferedReader bufr = new BufferedReader(isr);//緩衝//BufferedReader bufr = new BufferedReader( //new InputStreamReader(new FileInputStream("D://demo.txt")));可以綜合到一句。 /*int ch =0; ch = bufr.read(); System.out.println((char)ch); */ String line; while((line = bufr.readLine())!=null){ System.out.println(line); } isr.close(); }}三、InputStreamReader、BufferedReader真實案例(非編碼集)
import java.io.*;class UtilResource { private void initializeResource() { try { //讀取文件,並且以utf-8的形式寫出去BufferedReader bufread; String read; bufread = new BufferedReader(new InputStreamReader(ResourceHelper .getResourceInputStream("pinyin.txt"))); while ((read = bufread.readLine()) != null) { System.out.println(read); } bufread.close(); } catch (FileNotFoundException ex) { ex.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } }}注:其中pinyin.txt 放於項目的根目錄下
import java.io.BufferedInputStream;import java.io.FileInputStream;import java.io.FileNotFoundException;class ResourceHelper { /** * @param resourceName * @return * @return */ static BufferedInputStream getResourceInputStream(String resourceName) { try { return new BufferedInputStream(new FileInputStream(resourceName)); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }}總結:
InputStreamReader 類
是字節流通向字符流的橋樑,封了InputStream在裡頭, 它以較高級的方式,一次讀取一個一個字符,以文本格式輸入/ 輸出,可以指定編碼格式;
BufferedReader 類
BufferedReader 由Reader類擴展而來,提供通用的緩衝方式文本讀取,而且提供了很實用的readLine,讀取一個文本行,從字符輸入流中讀取文本,緩衝各個字符,從而提供字符、數組和行的高效讀取。
ps:InputStream、InputStreamReader和Reader的關係
InputStream:得到的是字節輸入流,InputStream.read("filename")之後,得到字節流
Reader:讀取的是字符流
InputStreamReader:從字節到字符的橋樑。 InputStreamReader(InputStream.read("filename"));
reader.read(InputStreamReader(InputStream in));便可從字節變為字符,打印顯示了。
java.io.Reader 和java.io.InputStream 組成了Java 輸入類。
Reader 用於讀入16位字符,也就是Unicode 編碼的字符;而InputStream 用於讀入ASCII 字符和二進制數據。
Reader支持16位的Unicode字符輸出,InputStream支持8位的字符輸出。
Reader和InputStream分別是I/O庫提供的兩套平行獨立的等級機構,1byte = 8bits InputStream、OutputStream是用來處理8位元的流,Reader、Writer是用來處理16位元的流。
而在JAVA語言中,byte類型是8位的,char類型是16位的,所以在處理中文的時候需要用Reader和Writer。
值得說明的是,在這兩種等級機構下,還有一道橋樑InputStreamReader、OutputStreamWriter負責進行InputStream到Reader的適配和由OutputStream到Writer的適配。
在Java中,有不同類型的Reader 輸入流對應於不同的數據源:
FileReader 用於從文件輸入; CharArrayReader 用於從程序中的字符數組輸入; StringReader 用於從程序中的字符串輸入; PipedReader 用於讀取從另一個線程中的PipedWriter 寫入管道的數據。
相應的也有不同類型的InputStream 輸入流對應於不同的數據源:FileInputStream,ByteArrayInputStream,StringBufferInputStream,PipedInputStream。
另外,還有兩種沒有對應Reader 類型的InputStream 輸入流: Socket 用於套接字; URLConnection 用於URL 連接。 這兩個類使用getInputStream() 來讀取數據。
相應的,java.io.Writer 和java.io.OutputStream 也有類似的區別。
關於InputStream.read(byte[] b)和InputStream.read(byte[] b,int off,int len)這兩個方法都是用來從流裡讀取多個字節的,有經驗的程序員就會發現,這兩個方法經常讀取不到自己想要讀取的個數的字節。比如第一個方法,程序員往往希望程序能讀取到b.length個字節,而實際情況是,系統往往讀取不了這麼多。仔細閱讀Java的API說明就發現了,這個方法並不保證能讀取這麼多個字節,它只能保證最多讀取這麼多個字節(最少1個)。因此,如果要讓程序讀取count個字節,最好用以下代碼:
byte[] b = new byte[count]; int readCount = 0; // 已經成功讀取的字節的個數while (readCount < count) { readCount += in.read(bytes, readCount, count - readCount); }用這段代碼可以保證讀取count個字節,除非中途遇到IO異常或者到了數據流的結尾(EOFException)