Java 之 FileReader FileInputStream InputStreamReader BufferedReader 做用與區別


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

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);code

相關文章
相關標籤/搜索