Java 中逐行读取文件有几种方式?
原文地址:http://www.programcreek.com/2011/03/java-read-a-file-line-by-line-code-example/
逐行处理文本文件是程序员做的常见事情。 Java I/O 包中有许多与此相关的类,也常常令人感到困惑。 这篇文章主要讲在 Java 中逐行读取文件的四种不同的方法。
1. FileInputStream 和 BufferedReader
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. FileReader 和 BufferedReader
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);
以上两种方式都可以逐行读取文本文件。
它们之间的主要区别是如何构造一个 BufferedReader 对象。 方法 1 使用 InputStreamReader,方法 2 使用 FileReader。 这两个类有什么区别? InputStreamReader 是从字节流到字符流的桥梁:它读取字节,并使用指定的字符集将其解码为字符。 InputStreamReader 可以处理除文件之外的其他输入流,例如网络连接,类路径资源,ZIP 文件等。
FileReader 是用于读取字符文件的便捷类。 该类的构造函数指定了默认字符编码和默认字节缓冲区大小。 FileReader 不允许您指定平台默认编码以外的编码。 因此,如果程序在具有不同编码的系统上运行,则不宜使用它。
所以,InputStreamReader 是比 FileReader 更安全的选择。
3. Files.newBufferedReader()
您还可以使用 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);
}
4. Java 8 Lambda
从 Java 8 开始,我们可以用一行代码来读取文本文件了。
Files.lines(new File("test.txt").toPath()).map(s -> s.trim())
.filter(s -> s.startsWith("abc")
.forEach(System.out::println);
想深入了解 inputstream 和 reader 相关概念,可以点击 http://www.programcreek.com/2012/05/java-io-class-hierarchy-diagram/