mos*_*aab 20 java-8 java-stream
dirPath包含200k文件.我想逐个阅读它们并做一些处理.以下代码片段会导致java.nio.file.FileSystemException: dirPath/file-N Too many open files.终端操作是否forEach()应该在移动到下一个之前关闭开放流(即打开文件)?换句话说,我是否必须为流式文件添加try-with-resources?
Files.list(dirPath)
.forEach(filePath -> {
Files.lines(filePath).forEach() { ... }
});
Run Code Online (Sandbox Code Playgroud)
ass*_*ias 17
否forEach不关闭流(由Files.list或创建Files.lines).它记录在javadoc中,例如Files.list:
返回的流封装了一个Reader.如果需要及时处理文件系统资源,则应使用try-with-resources构造来确保在流操作完成后调用流的close方法.
forEach在大多数情况下,嵌套是错误的工具.
代码
Files.list(dirPath).forEach(filePath -> Files.lines(filePath).forEach(line -> { ... });
Run Code Online (Sandbox Code Playgroud)
可以而且应该被替换
Files.list(dirPath).flatMap(filePath -> Files.lines(filePath)).forEach(line -> { ... });
Run Code Online (Sandbox Code Playgroud)
或者,因为在这种情况下并不容易:
Files.list(dirPath).flatMap(filePath -> {
try { return Files.lines(filePath);}
catch(IOException ex) { throw new UncheckedIOException(ex); }
}).forEach(line -> { });
Run Code Online (Sandbox Code Playgroud)
作为副作用,您可以免费获得以下内容:
Stream.flatMap(…):每个映射的流在其内容放入此流后关闭.
所以这是首选的解决方案.或者,使它完全正确:
try(Stream<Path> dirStream = Files.list(dirPath)) {
dirStream.flatMap(filePath -> {
try { return Files.lines(filePath);}
catch(IOException ex) { throw new UncheckedIOException(ex); }
}).forEach(line -> { });
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3799 次 |
| 最近记录: |