本文譯自Java read a file line by line – How Many Ways? 轉載請注明出處。
Java中的I/O類非常多,什么時候該用什么類經常讓人困惑。下面兩段代碼展示了如何一行一行的讀取一個文件:
方法1:
private static void readFile1(File fin) throws IOException {
FileInputStream fis = new FileInputStream(fin);
//Construct BufferedReader from InputStreamReader
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
}
方法2:
private static void readFile2(File fin) throws IOException {
// Construct BufferedReader from FileReader
BufferedReader br = new BufferedReader(new FileReader(fin));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
}
使用下面的代碼,就可以一行一行的讀取文件:
//use . to get current directory
File dir = new File(".");
File fin = new File(dir.getCanonicalPath() + File.separator + "in.txt");
readFile1(fin);
readFile2(fin);
兩種方法的不同之處是使用了不同的構造函數來構造BufferdReader,方法一使用了InputStreamReader而方法二使用了FileReader,兩者有什么區別呢?
根據Java文檔,“InputStreamReader是連接字節流和字符流的橋梁,它按字節讀取并且按照設定的編碼方式把字節解碼?!盜nputStreamReader除了可以處理文件外,還可以處理其他輸入流,比如網絡連接,classpath resources,ZIP文件等等。
“FileReader是一個可以方便地讀取字符文件的類。此類的構造方法假定默認字符編碼和默認字節緩沖區大小都是適當的。”FileReader不允許你自己設定編碼方式。因此,如果程序要運行在不同編碼的系統上時,最好不要使用FileReader。
綜上,相對于FileReader,InputStreamReader是一個更好的選擇。
值得提及的是,在文件路徑中不要使用/或者\,而是應該使用File.separator,這樣可以確保程序在任何操作系統上都可以正確運行。同時應該使用相對路徑,這樣就確保了文件路徑是決定正確的。
更新:
在Java 1.7中,你也可以使用下面的方法,其跟方法1是等價的。
Charset charset = Charset.forName("US-ASCII");
try (BufferedReader reader = Files.newBufferedReader(file, charset)) {
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException x) {
System.err.format("IOException: %s%n", x);
}
newBufferedReader實際上做了以下工作:
public static BufferedReader newBufferedReader(Path path, Charset cs){
CharsetDecoder decoder = cs.newDecoder();
Reader reader = new InputStreamReader(newInputStream(path), decoder);
return new BufferedReader(reader);
}
閱讀這些類的繼承圖也有助于理解這些inputstream和reader的關系:
http://www.programcreek.com/2012/05/java-io-class-hierarchy-diagram/
Reference: http://docs.oracle.com/javase/tutorial/essential/io/file.html