Нужно ли закрывать считыватели, даже если базовый InputStream
закрыт где-то еще?
Нет, они абсолютно не должны быть в этом сценарии.Но, как правило, в любом случае рекомендуется закрыть их.
Можно ли получить утечку памяти, не закрывая считыватели?
Нет, утечки памяти нет, есличто Reader
сам станет недоступным, как только вы покончили с ним.И кроме того, Reader
обычно не использует много памяти.
Более важный вопрос заключается в том, можно ли получить утечку resource , не закрывая Reader
.Ответ ... это зависит.
Если вы можете гарантировать, что базовый InputStream
всегда будет закрыт где-то еще в приложении, тогда , что принимаетзаботиться о возможных утечках памяти.
Если вы не можете гарантировать это, существует риск утечки ресурса.Базовые файловые дескрипторы уровня ОС являются ограниченным ресурсом (например) в Linux.Если JVM не закроет их, они могут закончиться, и некоторые системные вызовы начнут неожиданно завершаться с ошибкой.
Но если вы делаете , закройте Reader
тогда базовый InputStream
будет закрыт.
Вызов close()
более одного раза на InputStream
безвреден и почти ничего не стоит.
Единственный случай, когда вы не должны закрыть Reader
, - это когда было бы неправильно закрывать базовый InputStream
.Например, если вы закроете SocketInputStream
, остальная часть приложения, возможно, не сможет восстановить сетевое соединение.Аналогично, InputStream
, связанный с System.in
, обычно не может быть повторно открыт.
В этом случае на самом деле можно разрешить сборку Reader
, созданную в вашем методе, для сбора мусора.В отличие от InputStream
, типичный класс Reader
не переопределяет Object::finalize()
для закрытия источника данных.
@ Pshemo поднимает важный вопрос о дизайне системы.
Если вы принимаете InputStream
в качестве аргумента, то может быть неправильно заключать его в локальный Reader
... особенно BufferedReader
.`BufferedReader подвержен упреждающему чтению в потоке.Если поток будет использоваться вызывающей стороной после , который возвращает ваш метод, то любые данные, которые были считаны в буфер, но не использованы этим методом, могут быть потеряны.
Лучшей идеей для вызывающего абонента было бы передать Reader
.В качестве альтернативы, этот метод должен быть задокументирован как , вступающий во владение InputStream
И в этом случае оно должно всегда close()
оно.