我正在使用java NIO包的Files.lines()
方法读取文件,该文件给出type的输出Stream<String>
。在对字符串记录进行一些操作之后,我想将其写入文件。我尝试使用将其收集到列表中Collectors.toList()
,并且适用于较小的数据集。当我的文件有将近一百万行(记录)时,就会出现问题,该列表无法容纳那么多的记录。
// Read the file using Files.lines and collect it into a List
List<String> stringList = Files.lines(Paths.get("<inputFilePath>"))
.map(line -> line.trim().replaceAll("aa","bb"))
.collect(Collectors.toList());
// Writes the list into the output file
Files.write(Paths.get("<outputFilePath>"), stringList);
我正在寻找一种读取大文件,对其进行操作(如本.map()
例中的方法中所述)并将其写入文件而不将其存储到List(或集合)中的方法。
你可以尝试这样做(更新代码以关闭资源):
try (BufferedWriter writer = Files.newBufferedWriter(Path.of(outFile), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
Stream<String> lines = Files.lines(Path.of(inFile))) {
// Read the file using Files.lines and collect it into a List
lines.map(line -> line.trim().replaceAll("aa", "bb"))
.forEach(line -> {
try {
writer.write(line);
writer.newLine();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
writer.flush();
}
令人难以置信的是,这很可能是隐含的一点,但是将
writer
try放入资源块中(或try/catch
根据Java版本仅包装在纯文本中)将确保在发生UncheckedIOException
(或任何其他未经检查的Throwable
)情况下将其关闭。我尝试将其用于具有约3000条记录的输入文件,但遇到了异常
Exception in thread "main" java.io.UncheckedIOException: java.nio.charset.MalformedInputException: Input length = 1
。如果将记录数减少到10条,我不会遇到这个异常。此外,输出文件的所有记录都在一行中,而不是每行一个记录。的确如此,但是主要的想法是提供解决该问题的可能的解决方案,而不是专注于关闭资源。
我更新了代码以在每行之后添加一个休息点
forEach
这里不应该使用它,因为从流中获取一个迭代器并使用while ( it.hasNext() ) { String line = it.next(); }
不需要任何条件的标准惯用法在其上循环UncheckedIOException
(猜测哪种异常类型将捕获在外层)是更好的选择。