章
目
录
学习使用Java IO API、Common IO和Guava类将文件中的所有行读入ArrayList。
请记住,仅在可能需要在程序中多次引用文件内容的较小的文本文件中,将整个文件读入内存才是推荐的。在这种情况下,多次读取文件并不是理想的解决方案。因此,我们必须将文件内容一次读入List,然后在程序中的其他所有地方引用它。
1.将所有行读入ArrayList
要从文件中读取所有行,有多种高效解决方案,只需执行一个语句即可。让我们来看几个。
1.1 Java NIO的Files.readAllLines()
readAllLines()方法从文件中读取所有行。当所有字节被读取或发生I/O错误或其他运行时异常时,该方法将关闭文件。
try {
List<String> list = Files.readAllLines(
new File("data.txt").toPath(), Charsets.UTF_8 );
} catch (IOException e) {
e.printStackTrace();
}
1.2 Java NIO的Files.lines()
很多时候,我们可能想在读取行时进行处理。在这种情况下,我们可以将文件作为Stream读取并对流元素应用一些中间操作。
try (Stream<String> stream = Files.lines(Paths.get("data.txt"))) {
ArrayList<String> arrayList = stream
.collect(Collectors.toCollection(ArrayList::new));
}
catch (IOException e) {
e.printStackTrace();
}
1.3 Common IO的FileUtils.readLines()
此方法还将文件的内容逐行读入一个包含所有行的字符串List中。读取操作完成后,文件将被关闭。
try {
List<String> lines = FileUtils.readLines(
new File("data.txt"), StandardCharsets.UTF_8);
} catch (IOException e) {
e.printStackTrace();
}
1.4 Guava的Files.readLines()
此方法返回一个包含文件所有行的可变字符串列表。如需不可变列表,请使用Files.asCharSource(file, charset).readLines()。
try {
List<String> lines = com.google.common.io.Files.readLines(
new File("data.txt"), StandardCharsets.UTF_8);
} catch (IOException e) {
e.printStackTrace();
}
2.逐行读取文件并收集到List中
另一种读取文件中所有行的办法是,在while循环中逐行读取文件并将其添加到列表中。
这种解决方案给我们提供了在添加到列表之前进行必要的数据处理的机会。我们也可以选择是否包含或丢弃某一行。
2.1 使用Scanner
Scanner是一个简单的文本扫描器,用于解析基本类型和字符串,使用正则表达式。
我们可以使用nextLine()方法读取整行内容。要检查文件中是否还有更多内容,可以使用hasNext()方法。
try(Scanner s = new Scanner(new File("data.txt"))) {
ArrayList<String> list = new ArrayList<>();
while (s.hasNext()) {
list.add(s.next());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
2.2 使用BufferedReader
BufferedReader类也提供了类似Scanner类的方法,可以用来逐行读取文件内容并检查文件中是否还有剩余内容。
try (BufferedReader reader = new BufferedReader(
new FileReader("data.txt"))) {
ArrayList<String> list = new ArrayList<>();
while (reader.ready()) {
list.add(reader.readLine());
}
}
catch (IOException e) {
e.printStackTrace();
}
3.结论
正如所讨论的解决方案所示,从文件中读取所有行并不是一个难以解决的问题。我们可以根据需求选择解决方案,如果需要在添加行到列表之前进行一些中间处理的话。