Закрытие потоков в середине трубопроводов

Когда я выполняю этот код, который открывает много файлов во время потокового конвейера:

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

Я получаю исключение:

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

Проблема в том, чтоStream.count не закрывает поток после его прохождения. Но я не понимаю, почему это не следует делать, учитывая, что это терминальная операция. То же самое верно для других операций терминала, таких какreduce а такжеforEach. flatMap с другой стороны, закрывает потоки, из которых он состоит.

Документация говорит мне использовать оператор try-with-resouces-для закрытия потоков, если это необходимо. В моем случае я мог бы заменитьcount строка с чем-то вроде этого:

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

Но это шумно и некрасиво и может стать настоящим неудобством в некоторых случаях с большими и сложными трубопроводами.

Итак, мои вопросы следующие:

Почему потоки не были спроектированы так, чтобы терминальные операции закрывали потоки, над которыми они работают? Это позволило бы им лучше работать с потоками ввода-вывода.Каково лучшее решение для закрытия потоков ввода-вывода в конвейерах?

runtimizeException это метод, который оборачивает проверенное исключение вRuntimeExceptions.

Ответы на вопрос(5)

Ваш ответ на вопрос