在管道中间关闭流
当我执行此代码时,它在流管道期间打开了很多文件:
public static void main(String[] args) throws IOException {
Files.find(Paths.get("JAVA_DOCS_DIR/docs/api/"),
100, (path, attr) -> path.toString().endsWith(".html"))
.map(file -> runtimizeException(() -> Files.lines(file, StandardCharsets.ISO_8859_1)))
.map(Stream::count)
.forEachOrdered(System.out::println);
}
我得到一个例外:
java.nio.file.FileSystemException: /long/file/name: Too many open files
问题是,在完成遍历流时,它不会关闭流。但我不明白为什么它不应该,因为它是一个终端操作。这同样适用于其他终端操作,例如 和 。 另一方面关闭它所包含的流。Stream.count
reduce
forEach
flatMap
文档告诉我,如有必要,请使用 try-with-resouces-语句来关闭流。在我的情况下,我可以用这样的东西替换这行:count
.map(s -> { long c = s.count(); s.close(); return c; } )
但这是嘈杂和丑陋的,在某些情况下,对于大型,复杂的管道,这可能是一个真正的不便。
所以我的问题如下:
- 为什么没有将流设计为终端操作关闭它们正在处理的流?这将使它们更好地与IO流一起工作。
- 在管道中关闭 IO 流的最佳解决方案是什么?
runtimizeException
是将已检查的异常包装在 s 中的方法。RuntimeException