Java 8 Path Stream and FileSystemException (Too many open files)

风流意气都作罢 提交于 2020-02-14 08:03:10

问题


geniuses!

I'm practicing Java 8.

So if I do something like this:

Files.walk(Paths.get(corpusPathStr))
        .filter(path -> path.toFile().isFile())
        .forEach(path -> {
            try {
                Files.lines(path)
                        .forEach(...);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

I got FileSystemException error.

If I open a file under forEach, may too many files be opened?

Or are there other reasons causing FileSystemException (Too many open files)?

Thanks for your help in advance!


回答1:


Use

try(Stream<Path> stream = Files.walk(Paths.get(corpusPathStr))) {
    stream.filter(path -> Files.isRegularFile(path) && Files.isReadable(path))
          .flatMap(path -> {
                       try { return Files.lines(path); }
                       catch (IOException e) { throw new UncheckedIOException(e); }
                   })
          .forEach(...);
}
catch(UncheckedIOException ex) {
    throw ex.getCause();
}

The streams returned by Files.walk and Files.lines must be properly closed to release the resources, which you do by either, a try(…) construct or returning them in the mapping function of a flatMap operation.

Don’t use nested forEachs.

The UncheckedIOException might not only be thrown by our mapping function, but also the stream implementations. Translating it back to an IOException allows to treat them all equally.




回答2:


Files::line opens and reads the file in a lazy manner, i.e. Stream<String>. Since you're not closing any of your opened Streams you're getting such an error.

So when you're done reading a file you should close its handle. Since the returned Stream is AutoCloseable you can and should use a try-with-resource block.

try (Stream<Path> walk = Files.walk(Paths.get(""))) {
  walk.filter(Files::isRegularFile).forEach(path -> {
    try (Stream<String> lines = Files.lines(path)) {
      lines.forEach(System.out::println);
    } catch (IOException e) {
      e.printStackTrace();
    }
  });
} catch (IOException e) {
  e.printStackTrace();
}


来源:https://stackoverflow.com/questions/43067269/java-8-path-stream-and-filesystemexception-too-many-open-files

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!