我想使用Java创建和删除目录,但它无法正常工作.
File index = new File("/home/Work/Indexer1");
if (!index.exists()) {
index.mkdir();
} else {
index.delete();
if (!index.exists()) {
index.mkdir();
}
}
Run Code Online (Sandbox Code Playgroud) 当我执行此代码时,它会在流管道中打开大量文件:
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);
}
Run Code Online (Sandbox Code Playgroud)
我得到一个例外:
java.nio.file.FileSystemException: /long/file/name: Too many open files
Run Code Online (Sandbox Code Playgroud)
问题是Stream.count当流完成后不会关闭流.但鉴于它是终端操作,我不明白为什么不应该这样做.对于诸如reduce和之类的其他终端操作也是如此forEach.flatMap另一方面关闭它所包含的流.
该文档告诉我使用try-with-resouces语句在必要时关闭流.在我的情况下,我可以count用这样的东西替换线:
.map(s -> { long c = s.count(); s.close(); return c; } )
Run Code Online (Sandbox Code Playgroud)
但这很嘈杂,并且在某些情况下可能会给大型复杂的管道带来真正的不便.
所以我的问题如下:
runtimizeException是一种在RuntimeExceptions 中包装已检查异常的方法.
请考虑以下代码:
Path directory = Paths.get(/* some directory */);
Files.list(directory).forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)
终端操作(如forEach)是否关闭已打开的基础文件?
请参阅Files.list的javadoc的相关部分:
返回的流封装了DirectoryStream.如果需要及时处理文件系统资源,则应使用try-with-resources构造来确保在流操作完成后调用流的close方法.
如果它没有调用Stream.close(),那么在生成可维护代码时调用它的最佳选择是什么?
在Spring Data JPA文档中它说的关于流:
Stream可能会包装底层数据存储特定资源,因此必须在使用后关闭.您可以使用close()方法手动关闭Stream,也可以使用Java 7 try-with-resources块.
请参阅:http://docs.spring.io/spring-data/jpa/docs/1.10.1.RELEASE/reference/html/#repositories.query-streaming
如果我使用forEach,计数或其他终端操作处理流,它应该已经关闭(并且不能再次重复使用),我不必将流包装在额外的try-resources-block中(假设我的块没有'扔任何异常),或者我错在这里?