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

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

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

2 ответа

Решение

Как ага перегружен Files#lines(Path, Charset) метод состояний

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

Так что да, заверните Stream вернулся lines в try-with-resources заявление. (Или закройте его соответствующим образом.)

Есть хитрость, чтобы сделать Stream вызов реализации close() после работы терминала:

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

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

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

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

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


Для кода вопроса как есть есть еще более простое решение:

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

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

Другие вопросы по тегам