我有这个函数以递归方式打印目录中的所有文件的名称.问题是我的代码非常慢,因为它必须在每次迭代时访问远程网络设备.
我的计划是先递归加载目录中的所有文件,然后再使用正则表达式遍历所有文件,过滤掉我不想要的所有文件.有人有更好的建议吗?
public static printFnames(String sDir){
File[] faFiles = new File(sDir).listFiles();
for(File file: faFiles){
if(file.getName().matches("^(.*?)")){
System.out.println(file.getAbsolutePath());
}
if(file.isDirectory()){
printFnames(file.getAbsolutePath());
}
}
}
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 中包装已检查异常的方法.
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) 在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中(假设我的块没有'扔任何异常),或者我错在这里?
我有一个大文件,格式如下: -
第一行
第二行
第三行
第四行
第五行
Data1; Data2; Data3
Data1; Data2; Data3Data1
; Data2; Data3
......
....
我希望我的代码跳过前5行,然后对于其余的行,它会将行拆分为';' 并与第三项进行一些字符串比较.我希望将Java 8 Streams用于此目的,但无法弄清楚如何正确地解决它.我已经使用BufferedReader完成了我想做的事情,代码如下: -
try (BufferedReader reader = Files.newBufferedReader(dictionaryPath)) {
String line;
reader.readLine();
reader.readLine();
reader.readLine();
reader.readLine();
reader.readLine();
while ((line = reader.readLine()) != null) {
String[] dictData = line.split(";");
if (data.equals(dictData[2])) {
System.out.println("Your Data Item is: " + dictData[0]);
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
但我不确定如何使用Java 8流实现与上面相同的功能.我正在尝试以下内容:
try (Stream<String> lines = Files.lines(dictionaryPath)) {
lines.skip(5).map(line -> line.split(";")).flatMap(Arrays::stream)
Run Code Online (Sandbox Code Playgroud)
但无法理解更多.我希望得到一些帮助.