本文译自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是连接字节流和字符流的桥梁,它按字节读取并且按照设定的编码方式把字节解码。”InputStreamReader除了可以处理文件外,还可以处理其他输入流,比如网络连接,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