Question: When I execute this code which opens a lot of files during a stream pipeline: 

```java
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);
}

```

I get an exception:

```java
java.nio.file.FileSystemException: /long/file/name: Too many open files

```

The problem is that `Stream.count` does not close the stream when it is done traversing it. But I don't see why it shouldn't, given that it is a terminal operation. The same holds for other terminal operations such as `reduce` and `forEach`. `flatMap` on the other hand closes the streams it consists of.

The documentation tells me to use a try-with-resouces-statement to close streams if necessary. In my case I could replace the `count` line with something like this:

```java
.map(s -> { long c = s.count(); s.close(); return c; } )

```

But that is noisy and ugly and could be a real inconvenience in some cases with big, complex pipelines.

So my questions are the following:

1. Why were the streams not designed so that terminal operations close the streams they are working on? That would make them work better with IO streams.
2. What is the best solution for closing IO streams in pipelines?

---

`runtimizeException` is a method that wraps checked exception in `RuntimeException`s.

Answer: 
You will need to call `close()` in this stream operation, which will cause all underlying close handlers to be called.

Better yet, would be to wrap your whole statement in a *try-with-resources* block, as then it will automagically call the close handler.

This may not be possibility in your situation, this means that you will need to handle it yourself in some operation. Your current methods may not be suited for streams at all.

It seems like you indeed need to do it in your second `map()` operation.
Here is an alternative which uses another method from `Files` and will avoid leaking file descriptors:

```
Files.find(Paths.get("JAVA_DOCS_DIR/docs/api/"),
    100, (path, attr) -> path.toString().endsWith(".html"))
    .map(file -> runtimizeException(() -> Files.readAllLines(file, StandardCharsets.ISO_8859_1).size())
    .forEachOrdered(System.out::println);

```

Unlike your version, it will return an `int` instead of a `long` for the line count; but you don't have files with that many lines, do you?