Java 中 FileReader 和 BufferedReader 的區別
一、概述
FileReader
和BufferedReader
是兩個可以從輸入流中讀取字符的類。
在本教程中,我們將看到它們之間的區別。
2. FileReader
FileReader
類可以從文件中讀取字符流。而且,它只能一個字符一個字符地讀取文件,每次我們調用它的read()
方法時,它直接訪問硬盤上的文件並從中讀取一個字符。因此,當從文件中讀取字符時, FileReader
本身非常緩慢且效率低下。此外, FileReader
只能從文件中讀取字符,不能讀取其他類型的輸入流。
2.1.構造器
FileReader
具有三個構造函數:
-
FileReader(File file)
:接收一個File
實例作為參數 -
FileReader(FileDescriptor fd)
:接收一個FileDescriptor
作為參數 -
FileReader(String fileName)
:接收文件名(包括其路徑)作為參數
2.2.它返回什麼
每次我們調用read()
方法時,它都會返回一個整數值,表示從文件中讀取的字符的 Unicode 值,如果到達字符流的末尾,則返回 -1。
2.3.例子
讓我們看一個使用FileReader
從包含“qwerty”作為內容的文本文件中讀取字符的示例:
@Test
public void whenReadingAFile_thenReadsCharByChar() {
StringBuilder result = new StringBuilder();
try (FileReader fr = new FileReader("src/test/resources/sampleText2.txt")) {
int i = fr.read();
while(i != -1) {
result.append((char)i);
i = fr.read();
}
} catch (IOException e) {
e.printStackTrace();
}
assertEquals("qwerty", result.toString());
}
在上面的代碼中,我們在將read()
方法的返回值附加到結果字符串之前將其轉換為char
。
3. BufferedReader
BufferedReader
類創建一個緩衝區來保存來自字符輸入流的數據。此外,輸入流可以是文件、控制台、字符串或任何其他類型的字符流。
它的構造函數接收一個Reader
作為字符輸入流。因此,我們可以將任何實現了Reader
抽像類的類交給BufferedReader
作為讀取字符的輸入流。
當我們開始從BufferedReader
讀取時,它會從輸入流中讀取整個數據塊並將其存儲在緩衝區中。之後,如果我們繼續從BufferedReader
讀取,它將返回緩衝區中的字符而不是底層字符流,直到緩衝區為空。然後它將從輸入流中讀取另一個數據塊並將其存儲在緩衝區中以供進一步讀取調用。
BufferedReader
類減少了對輸入流調用的讀取操作,從緩衝區讀取通常比訪問底層輸入流快得多。因此, BufferedReader
提供了一種更快、更有效的方式來從字符流中讀取字符。
3.1.構造函數
BufferedReader
有兩個構造函數:
-
BufferedReader(Reader in)
:接收字符輸入流(必須實現Reader
抽像類)作為參數 -
BufferedReader(Reader in, int sz)
:接收字符輸入流和緩衝區大小作為參數
3.2.它返回什麼
如果我們調用read()
方法,它會返回一個 int 值,即從輸入流中讀取的字符的 Unicode 值。此外,如果我們調用readLine()
方法,它會從緩衝區中讀取整行並將其作為字符串值返回。
3.3.例子
讓我們使用BufferedReader
從包含三行內容的文本文件中讀取字符:
@Test
public void whenReadingAFile_thenReadsLineByLine() {
StringBuilder result = new StringBuilder();
try (BufferedReader br = new BufferedReader(new FileReader("src/test/resources/sampleText1.txt"))) {
String line;
while((line = br.readLine()) != null) {
result.append(line);
result.append('\n');
}
} catch (IOException e) {
e.printStackTrace();
}
assertEquals("first line\nsecond line\nthird line\n", result.toString());
}
以上測試代碼通過,說明BufferedReader
成功從文件中讀取了全部三行文本。
4.有什麼區別?
BufferedReader
比FileReader
更快更高效,因為它從輸入流中讀取整個數據塊並將其保存在緩衝區中以供進一步讀取調用,而FileReader
需要訪問每個字符的文件。此外, FileReader
只能逐個字符地讀取文件,而BufferedReader
有其他方法,如readLine(),
可以從緩衝區中讀取整行。最後, FileReader
只能從文件中讀取,而BufferedReader
可以從任何類型的字符輸入流(文件、控制台、字符串等)中讀取:
FileReader | BufferedReader |
速度較慢且效率較低 | 更快更高效 |
只能逐字閱讀 | 可以閱讀字符和行 |
只能從文件中讀取 | 可以從任何類型的字符流中讀取 |
如果我們從小文件讀取並且對文件數據的讀取調用很少, FileReader
就足夠了。但是,對於大文件或者對數據有很多讀取操作的時候, BufferedReader
是更好的選擇。
5.總結
在本教程中,我們學習瞭如何使用FileReader
和BufferedReader
以及它們之間的區別。
與往常一樣,本教程的完整源代碼可在 GitHub 上獲得。