天天看點

Java 之InputStream FileInputStream FileReader InputStreamReader BufferedReader

文章出處:http://www.cnblogs.com/lianghui66/p/3303546.html

java.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);

如果處理純文字檔案,建議使用FileReader,因為更友善,也更适合閱讀;但是要注意編碼問題!

其他情況(處理非純文字檔案),FileInputStream是唯一的選擇;FileInputStream是進Socket通訊時會用到很多,如将檔案流是Stream的方式傳向伺服器!

一般用法:

FileReader fr = new FileReader("ming.txt");

  char[] buffer = new char[1024];

  int ch = 0;

  while((ch = fr.read())!=-1 )

  {

   System.out.print((char)ch);

  }

InputStreamReader類

 以文本格式輸入/輸出,可以指定編碼格式;

 主要方法:

getEncoding(),read();

 一般用法:

InputStreamReader isr = new InputStreamReader(new FileInputStream("ming.txt"));

  while((ch = isr.read())!=-1)

  {

   System.out.print((char)ch);

  }

BufferedReader類

一般用法:

BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("ming.txt")));

  String data = null;

  while((data = br.readLine())!=null)

  {

   System.out.println(data);

  }