4

I read from several posts and docs that resources in a stream will not be closed automatically.

  1. Does collect operation on Stream close the stream and underlying resources?

  2. Why is Files.lines (and similar Streams) not automatically closed?

But I'm wondering if I have a nice way to close resources in a stream from intermediate operations. Like code below:

public class MyTest {
    @Test
    public void main() throws Exception {
        test().forEach(System.out::println);
    }

    public List<String> test() throws Exception {
        Path myPath = Paths.get(this.getClass().getClassLoader().getResource("test").toURI());

        Function<Path, Stream<String>> mapper = path -> {
            try {
                return Files.lines(path, StandardCharsets.UTF_8);
            } catch (IOException e) {
                throw new UncheckedIOException("File cannot be read: " + path, e);
            }
        };

        try {
            return Files.list(myPath).peek(System.out::println)
                    .flatMap(mapper).peek(System.out::println)
                    .map(s -> s + " mapped").peek(System.out::println)
                    .collect(Collectors.toList());
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }
}

In order to avoid IllegalStateException(something like "stream is already closed"), I think I'm not able to use try-with-resources in the lambda expression named mapper, but when is the good timing to close the stream?

Community
  • 1
  • 1
choasia
  • 10,404
  • 6
  • 40
  • 61
  • Apparently you haven’t read the linked Q&As *completely*, namely [this answer](http://stackoverflow.com/a/31179709/2711488). `flatMap` already takes care about closing the stream returned by `mapper`. – Holger Dec 02 '16 at 13:23
  • @Holger Hi, thanks a lot. I found you said `While it looks more concise it has the disadvantage over try with resources that the current implementation doesn’t close the stream if an exception occurs in-between.` in the linked answer, are there any solutions when I need to make sure that all the resources are closed even though exceptions happened? – choasia Dec 02 '16 at 13:45
  • There is no way to fix such things on the application side. But apparently, the JRE developers already fixed this. I’m going to check which version the fix was added, then I’ll update that answer. – Holger Dec 02 '16 at 14:48
  • @Holger That will be really appreciated. So actually we can use flatMap without considering the leak of resources under latest JRE, right? – choasia Dec 02 '16 at 23:50
  • 1
    I already removed that part. I couldn’t retrace the issue, even under older JREs, so most likely the error was on my side back then. The resources are closed as they should, so you can use `flatMap` without worrying about resource leaks. – Holger Dec 05 '16 at 09:58
  • Possible duplicate of [Does collect operation on Stream close the stream and underlying resources?](https://stackoverflow.com/questions/31171489/does-collect-operation-on-stream-close-the-stream-and-underlying-resources) – walen Mar 22 '19 at 10:39

0 Answers0