本文譯自Java read a file line by line – How Many Ways? 轉(zhuǎn)載請(qǐng)注明出處。
Java中的I/O類非常多栗竖,什么時(shí)候該用什么類經(jīng)常讓人困惑攒暇。下面兩段代碼展示了如何一行一行的讀取一個(gè)文件:
方法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);
兩種方法的不同之處是使用了不同的構(gòu)造函數(shù)來(lái)構(gòu)造BufferdReader蚤认,方法一使用了InputStreamReader而方法二使用了FileReader队魏,兩者有什么區(qū)別呢振峻?
根據(jù)Java文檔臼疫,“InputStreamReader是連接字節(jié)流和字符流的橋梁,它按字節(jié)讀取并且按照設(shè)定的編碼方式把字節(jié)解碼扣孟√痰蹋”InputStreamReader除了可以處理文件外,還可以處理其他輸入流,比如網(wǎng)絡(luò)連接鸽斟,classpath resources拔创,ZIP文件等等。
“FileReader是一個(gè)可以方便地讀取字符文件的類富蓄。此類的構(gòu)造方法假定默認(rèn)字符編碼和默認(rèn)字節(jié)緩沖區(qū)大小都是適當(dāng)?shù)氖T铩!盕ileReader不允許你自己設(shè)定編碼方式立倍。因此灭红,如果程序要運(yùn)行在不同編碼的系統(tǒng)上時(shí),最好不要使用FileReader口注。
綜上变擒,相對(duì)于FileReader,InputStreamReader是一個(gè)更好的選擇寝志。
值得提及的是赁项,在文件路徑中不要使用/或者\(yùn),而是應(yīng)該使用File.separator澈段,這樣可以確保程序在任何操作系統(tǒng)上都可以正確運(yùn)行悠菜。同時(shí)應(yīng)該使用相對(duì)路徑,這樣就確保了文件路徑是決定正確的败富。
更新:
在Java 1.7中悔醋,你也可以使用下面的方法,其跟方法1是等價(jià)的兽叮。
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實(shí)際上做了以下工作:
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的關(guān)系:
http://www.programcreek.com/2012/05/java-io-class-hierarchy-diagram/
Reference: http://docs.oracle.com/javase/tutorial/essential/io/file.html