FileReader FileInputStream InputStreamReader BufferedReader 作用與區別

ava.io下面有兩個抽象類:InputStream和Reader
InputStream是表示字節輸入流的所有類的超類
Reader是用於讀取字符流的抽象類
InputStream提供的是字節流的讀取,而非文本讀取,這是和Reader類的根本區別。
即用Reader讀取出來的是char數組或者String ,使用InputStream讀取出來的是byte數組。
弄清了兩個超類的根本區別,再來看他們底下子類的使用,這裏只對最常用的幾個說明

InputStream 
   | __FileInputStream 


FileInputStream 從文件系統中的某個文件中獲得輸入字節。
構造方法摘要  
FileInputStream (File  file) 
          通過打開一個到實際文件的連接來創建一個 FileInputStream ,該文件通過文件系統中的 File 對象 file 指定。 
FileInputStream (FileDescriptor  fdObj) 
          通過使用文件描述符 fdObj 創建一個 FileInputStream ,該文件描述符表示到文件系統中某個實際文件的現有連接。 
FileInputStream (String  name) 
          通過打開一個到實際文件的連接來創建一個 FileInputStream ,該文件通過文件系統中的路徑名 name 指定。 
 
 
Reader

   |——BufferedReader 
   |___InputStreamReader 
         |__FileReader 


BufferedReader : 從字符輸入流中讀取文本,緩衝各個字符,從而實現字符、數組和行的高效讀取。
 
構造方法摘要  
BufferedReader (Reader  in) 
          創建一個使用默認大小輸入緩衝區的緩衝字符輸入流。 
BufferedReader (Reader  in, int sz) 
          創建一個使用指定大小輸入緩衝區的緩衝字符輸入流。 
BufferedReader (Java Platform SE 6) 
BufferedReader的最大特點就是緩衝區的設置。通常Reader 所作的每個讀取請求都會導致對底層字符或字節流進行相應的讀取請求,如果沒有緩衝,則每次調用 read() 或 readLine() 都會導致從文件中讀取字節,並將其轉換爲字符後返回,而這是極其低效的。 
使用BufferedReader可以指定緩衝區的大小,或者可使用默認的大小。大多數情況下,默認值就足夠大了。 
因此,建議用 BufferedReader 包裝所有其 read() 操作可能開銷很高的 Reader(如 FileReader 和InputStreamReader)。例如, 
 BufferedReader in
   = new BufferedReader(new FileReader("foo.in"));
 將緩衝指定文件的輸入。 
InputStreamReader (Java Platform SE 6) 
InputStreamReader 是字節流通向字符流的橋樑:它使用指定的 charset 讀取字節並將其解碼爲字符。它使用的字符集可以由名稱指定或顯式給定,或者可以接受平臺默認的字符集。 
 
構造方法摘要  
InputStreamReader (InputStream  in) 
          創建一個使用默認字符集的 InputStreamReader。 
InputStreamReader (InputStream  in, Charset  cs) 
          創建使用給定字符集的 InputStreamReader。 
InputStreamReader (InputStream  in, CharsetDecoder  dec) 
          創建使用給定字符集解碼器的 InputStreamReader。 
InputStreamReader (InputStream  in, String  charsetName) 
          創建使用指定字符集的 InputStreamReader。 
 
每次調用 InputStreamReader 中的一個 read() 方法都會導致從底層輸入流讀取一個或多個字節。要啓用從字節到字符的有效轉換,可以提前從底層流讀取更多的字節,使其超過滿足當前讀取操作所需的字節。 
爲了達到最高效率,可要考慮在 BufferedReader 內包裝 InputStreamReader。例如: 
 BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
InputStreamReader最大的特點是可以指轉換的定編碼格式
,這是其他類所不能的,從構造方法就可看出,
這一點在讀取中文字符時非常有用

FileReader
1)FileReader類介紹:
InputStreamReader類的子類,所有方法(read()等)都從父類InputStreamReader中繼承而來;
2)與InputStreamReader類的區別:
構造方法摘要  
FileReader (File  file) 
          在給定從中讀取數據的 File 的情況下創建一個新 FileReader 。 
FileReader (FileDescriptor  fd) 
          在給定從中讀取數據的 FileDescriptor 的情況下創建一個新 FileReader 。 
FileReader (String  fileName) 
          在給定從中讀取數據的文件名的情況下創建一個新 FileReader  

該類與它的父類InputStreamReader的主要不同在於構造函數,主要區別也就在於構造函數!
InputStreamReader的構造函數中看到,參數爲InputStream和編碼方式,可以看出,
當要指定編碼方式時,必須使用InputStreamReader
類;而FileReader構造函數的參數與FileInputStream同,爲File對象或表示path的String,可以看出,當要根據File對象或者String讀取一個文件時,用FileReader;
我想FileReader子類的作用也就在於這個小分工吧。該類與它的父類InputStreamReader
的主要不同在於構造函數,主要區別也就在於構造函數!
InputStreamReader
的構造函數中看到,參數爲InputStream和編碼方式,可以看出,
當要指定編碼方式時,必須使用InputStreamReader
類;而FileReader構造函數的參數與FileInputStream
同,爲File對象或表示path的String,可以看出,當要根據File對象或者String讀取一個文件時,用FileReader;
我想FileReader子類的作用也就在於這個小分工吧。
二 聯繫與區別 
(1)字符與字節: 
FileInputStream 類以二進制輸入/輸出,I/O速度快且效率搞,但是它的read()方法讀到的是一個字節(二進制數據),很不利於人們閱讀,而且無法直接對文件中的字符進行操作,比如替換,查找(必須以字節形式操作);
而Reader類彌補了這個缺陷,可以以文本格式輸入/輸出,非常方便;比如可以使用while((ch = filereader.read())!=-1 )循環來讀取文件;可以使用BufferedReader的readLine()方法一行一行的讀取文本。
(2)編碼
InputStreamReader ,它是字節轉換爲字符的橋樑。 你可以在構造器重指定編碼的方式,如果不指定的話將採用底層操作系統的默認編碼方式,例如GBK等。 
FileReader與InputStreamReader 涉及編碼轉換(指定編碼方式或者採用os默認編碼),可能在不同的平臺上出現亂碼現象!而FileInputStream 以二進制方式處理,不會出現亂碼現象. 
因此要指定編碼方式時,必須使用InputStreamReader 類,所以說它是字節轉換爲字符的橋樑;
(3) 緩存區
    BufferReader類用來包裝所有其 read() 操作可能開銷很高的 Reader(如 FileReader 和InputStreamReader)。
(4)規範用法
總結以上內容,得出比較好的規範用法: 
1) File file = new File ("hello.txt"); 
FileInputStream in=new FileInputStream (file); 
2) File file = new File ("hello.txt"); 
FileInputStream in=new FileInputStream (file); 
InputStreamReader inReader=new InputStreamReader (in,"UTF-8"); 
BufferedReader bufReader=new BufferedReader(inReader); 
3) File file = new File ("hello.txt"); 
FileReader fileReader=new FileReader(file); 

BufferedReader bufReader=new BufferedReader(fileReader);


一、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;
  }
}

.InputStream、OutputStream

處理字節流的抽象類

InputStream 是字節輸入流的所有類的超類,一般我們使用它的子類,如FileInputStream等.

OutputStream是字節輸出流的所有類的超類,一般我們使用它的子類,如FileOutputStream等.

2.InputStreamReader  OutputStreamWriter

處理字符流的抽象類

InputStreamReader 是字節流通向字符流的橋樑,它將字節流轉換爲字符流.

OutputStreamWriter是字符流通向字節流的橋樑,它將字符流轉換爲字節流.

3.BufferedReader BufferedWriter

BufferedReader 由Reader類擴展而來,提供通用的緩衝方式文本讀取,readLine讀取一個文本行,

從字符輸入流中讀取文本,緩衝各個字符,從而提供字符、數組和行的高效讀取。

BufferedWriter  由Writer 類擴展而來,提供通用的緩衝方式文本寫入, newLine使用平臺自己的行分隔符,

將文本寫入字符輸出流,緩衝各個字符,從而提供單個字符、數組和字符串的高效寫入。

InputStream能從來源處讀取一個一個byte,
所以它是最低級的,
例:

  1. import java.io.*;    
  2. public class Main {    
  3.     public static void main(String[] args) {    
  4.             
  5.         try {    
  6.             FileInputStream fis=new FileInputStream("d://desktop//test.txt");    
  7.             int i;    
  8.                 
  9.             try {    
  10.                 while((i=fis.read()) != -1){    
  11.                     System.out.println(i);    
  12.                 }    
  13.                 /*假設test.txt檔裡頭只有一個文字 "陳" ,且其編碼為 utf8 
  14.                  * 輸出 
  15.                  *  233 
  16.                     153 
  17.                     179 
  18.                  */   
  19.             } catch (IOException e) {    
  20.                 // TODO Auto-generated catch block    
  21.                 e.printStackTrace();    
  22.             }    
  23.                 
  24.                 
  25.         } catch (FileNotFoundException e) {    
  26.             // TODO Auto-generated catch block    
  27.             e.printStackTrace();    
  28.         }    
  29.                     
  30.     }    
  31. }  

[java] view plain copy
  1. import java.io.*;     
  2. public class Main {     
  3.     public static void main(String[] args) {     
  4.              
  5.         try {     
  6.             FileInputStream fis=new FileInputStream("d://desktop//test.txt");     
  7.             int i;     
  8.                  
  9.             try {     
  10.                 while((i=fis.read()) != -1){     
  11.                     System.out.println(i);     
  12.                 }     
  13.                 /*假設test.txt檔裡頭只有一個文字 "陳" ,且其編碼為 utf8   
  14.                  * 輸出   
  15.                  *  233   
  16.                     153   
  17.                     179   
  18.                  */    
  19.             } catch (IOException e) {     
  20.                 // TODO Auto-generated catch block     
  21.                 e.printStackTrace();     
  22.             }     
  23.                  
  24.                  
  25.         } catch (FileNotFoundException e) {     
  26.             // TODO Auto-generated catch block     
  27.             e.printStackTrace();     
  28.         }     
  29.                      
  30.     }     
  31. }   

InputStreamReader
InputStreamReader封裝了InputStream在裏頭,
它以較高級的方式,一次讀取一個一個字符,
下例是假設有一個編碼爲utf8的文檔,
其內容只有一箇中文字 "陳"

  1. import java.io.*;    
  2. public class Main {    
  3.     public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {    
  4.                     
  5.             FileInputStream fis=new FileInputStream("d://desktop//test.txt");    
  6.             try {    
  7.                 InputStreamReader isr=new InputStreamReader(fis,"utf8");    
  8.                 int i;    
  9.                 while((i=isr.read()) != -1){    
  10.                     System.out.println((char)i);  //輸出  陳    
  11.                 }    
  12.             } catch (Exception e) {    
  13.                 // TODO Auto-generated catch block    
  14.                 e.printStackTrace();    
  15.             }                                           
  16.                     
  17.     }    
  18. }   

[java] view plain copy
  1. import java.io.*;     
  2. public class Main {     
  3.     public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {     
  4.                      
  5.             FileInputStream fis=new FileInputStream("d://desktop//test.txt");     
  6.             try {     
  7.                 InputStreamReader isr=new InputStreamReader(fis,"utf8");     
  8.                 int i;     
  9.                 while((i=isr.read()) != -1){     
  10.                     System.out.println((char)i);  //輸出  陳     
  11.                 }     
  12.             } catch (Exception e) {     
  13.                 // TODO Auto-generated catch block     
  14.                 e.printStackTrace();     
  15.             }                                            
  16.                      
  17.     }     
  18. }    

BufferedReader
BufferedReader則是比InputStreamReader更高級,
它封裝了StreamReader類,
一次讀取取一行的字符

  1. import java.io.*;    
  2. public class Main {    
  3.     public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {    
  4.                     
  5.             FileInputStream fis=new FileInputStream("d://desktop//test.txt");    
  6.                 
  7.             try {    
  8.                 InputStreamReader isr=new InputStreamReader(fis,"utf8");                    
  9.                 BufferedReader br=new BufferedReader(isr);    
  10.                     
  11.                 String line;    
  12.                 while((line=br.readLine()) != null){    
  13.                     System.out.println(line);    
  14.                 }    
  15.             } catch (Exception e) {    
  16.                 // TODO Auto-generated catch block    
  17.                 e.printStackTrace();    
  18.             }                                           
  19.                     
  20.     }    
  21. }   

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

12.4  轉換流--OutputStreamWriter類與InputStreamReader類

整個IO包實際上分爲字節流和字符流,但是除了這兩個流之外,還存在一組字節流-字符流的轉換類。

OutputStreamWriter:是Writer的子類,將輸出的字符流變爲字節流,即將一個字符流的輸出對象變爲字節流輸出對象。

InputStreamReader:是Reader的子類,將輸入的字節流變爲字符流,即將一個字節流的輸入對象變爲字符流的輸入對象。

如果以文件操作爲例,則內存中的字符數據需要通過OutputStreamWriter變爲字節流才能保存在文件中,讀取時需要將讀入的字節流通過InputStreamReader變爲字符流,轉換步驟如圖12-7所示。

 

(點擊查看大圖)圖12-7  轉換步驟

從圖12-7中可以清楚地發現,不管如何操作,最終全部是以字節的形式保存在文件中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章