Мне нужно закрыть InputStream после закрытия Reader
Мне было интересно, есть ли необходимость в том, чтобы закрыть InputStream, после того как я закрою читателя?
try {
inputStream = new java.io.FileInputStream(file);
reader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
}
catch (Exception exp) {
log.error(null, exp);
}
finally {
if (false == close(reader)) {
return null;
}
// Do I need to close inputStream as well?
if (false == close(inputStream)) {
return null;
}
}
Ответы
Ответ 1
Нет, вам не обязательно.
Так как подход декоратора, используемый для потоков в Java, может создавать новые потоки или считыватели, присоединяя их к другим, это будет автоматически обрабатываться реализацией InputStreamReader
.
Если вы посмотрите на его источник InputStreamReader.java
, вы увидите, что:
private final StreamDecoder sd;
public InputStreamReader(InputStream in) {
...
sd = StreamDecoder.forInputStreamReader(in, this, (String)null);
...
}
public void close() throws IOException {
sd.close();
}
Таким образом, операция закрытия фактически закрывает InputStream
, лежащую в основе считывателя потока.
EDIT: Я хочу быть уверенным, что закрытие StreamDecoder
также работает на входном потоке, следите за обновлениями.
Проверено, в StreamDecoder.java
void implClose() throws IOException {
if (ch != null)
ch.close();
else
in.close();
}
который вызывается при вызове sd close.
Ответ 2
Технически, закрытие Reader
закроет InputStream
. Однако, если произошел сбой между открытием InputStream
и созданием Reader
, вы все равно должны закрыть InputStream
. Если вы закроете InputStream
[ресурс], не должно быть веской причины закрыть Reader
[декоратор]. Есть также популярные ошибки, когда закрытие декоратора может вызвать исключение перед закрытием украшенного. Итак:
Resource resource = acquire();
try {
Decorator decorated = decorate(resource);
use(decorated);
} finally {
resource.release();
}
Есть некоторые осложнения, на которые следует обратить внимание. Некоторые декораторы могут фактически содержать собственные ресурсы из-за их реализации. Декораторы вывода обычно нужно очищать, но только в счастливом случае (поэтому в блоке try
не finally
).
Ответ 3
Вам не нужно закрывать поток, если вы close()
читатель.
Закрывает поток и освобождает любые системные ресурсы, связанные с Это. Как только поток был закрыт, далее read(), ready(), mark(), reset(), или вызовы skip() будут вызывать исключение IOException. Закрытие ранее закрытый поток не влияет.
Ответ 4
Нет, вы не читатель не закроете базовый InputStream
Ответ 5
Приписывая источнику обнюхивание, читатель закрывает свой основной входной поток. Согласно javadoc, он швы, что InputStreamReader "закрывает поток" при вызове reader.close().
Я не уверен, что ANY Reader должен закрыть свои источники, когда вы будете читать reader.close(). Я думаю, что это важно, поэтому ваш код может использовать читателя независимо от его конкретного типа.
В любом случае имеет смысл, что это принудительно.