Собирает ли транзакция в Stream поток потока и основные ресурсы?

Нужно ли обертывать код в try-with-resources, чтобы убедиться, что основной файл закрыт?

List<String> rows = Files.lines(inputFilePath).collect(Collectors.toList());

Ответ 1

Поскольку javadoc перегруженного Files#lines(Path, Charset) метода указывает

Возвращенный поток инкапсулирует a Reader. Если своевременное удаление файла требуются системные ресурсы, конструкция try-with-resources должна использоваться для обеспечения того, чтобы метод закрытия потока был вызван после потоковые операции завершены.

Итак, положите Stream, возвращенный lines в инструкции try-with-resources. (Или close соответствующим образом.)

Ответ 2

Существует трюк, чтобы выполнить реализацию Stream при вызове close() после операции терминала:

List<String> rows = Stream.of(Files.lines(inputFilePath)).flatMap(s->s)
                   .collect(Collectors.toList());

Он просто создает поток, инкапсулирующий поток строк как один элемент, и использует flatMap с функцией идентификации (Function.identity() тоже будет работать), чтобы снова включить его в поток строк.

Интересным моментом является свойство Stream.flatMap(…):

Каждый отображаемый поток закрывается после того, как его содержимое было помещено в этот поток.

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


Для кода вопросов as-is существует еще более простое решение:

List<String> rows = Files.readAllLines(inputFilePath);

Считывает все строки и закрывает все ресурсы...