it-roy-ru.com

Нужно ли закрыть () и FileReader, и BufferedReader?

Я читаю локальный файл, используя BufferedReader, обернутый вокруг FileReader:

BufferedReader reader = new BufferedReader(new FileReader(fileName));
// read the file
// (error handling snipped)
reader.close();

Нужно ли мне также close()FileReader, или обработчик будет это обрабатывать? Я видел код, где люди делают что-то вроде этого:

FileReader fReader = new FileReader(fileName);
BufferedReader bReader = new BufferedReader(fReader);
// read the file
// (error handling snipped)
bReader.close();
fReader.close();

Этот метод вызывается из сервлета, и я хотел бы убедиться, что я не оставляю открытых дескрипторов.

171
Zilk

нет.

BufferedReader.close()

закрывает поток в соответствии с javadoc для BufferedReader и InputStreamReader

так же как

FileReader.close()

делает.

194
Atmocreations

Как уже отмечали другие, вам нужно только закрыть внешнюю обертку.

BufferedReader reader = new BufferedReader(new FileReader(fileName));

Существует очень малая вероятность того, что это может привести к утечке дескриптора файла, если конструктор BufferedReader вызвал исключение (например, OutOfMemoryError). Если ваше приложение находится в этом состоянии, то насколько тщательной должна быть ваша очистка, может зависеть от того, насколько важно не лишать ОС ресурсов, которые она может захотеть выделить другим программам.

Интерфейс Closeable можно использовать, если в Java 5 или 6 возможен сбой конструктора-оболочки:

Reader reader = new FileReader(fileName);
Closeable resource = reader;
try {
  BufferedReader buffered = new BufferedReader(reader);
  resource = buffered;
  // TODO: input
} finally {
  resource.close();
}

Код Java 7 должен использовать шаблон try-with-resources:

try (Reader reader = new FileReader(fileName);
    BufferedReader buffered = new BufferedReader(reader)) {
  // TODO: input
}
90
McDowell

Согласно источнику BufferedReader, в этом случае bReader.close вызывает fReader.close, поэтому технически вам не нужно вызывать последний.

6
Csaba_H

Исходный код для BufferedReader показывает, что базовый уровень закрывается при закрытии BufferedReader.

4
Brian Agnew

После проверки исходного кода я обнаружил, что для примера:

FileReader fReader = new FileReader(fileName);
BufferedReader bReader = new BufferedReader(fReader);

метод close () на BufferedReader объект будет вызывать абстрактный метод close () Читатель класс, который в конечном итоге вызовет реализованный метод в InputStreamReader класс, который затем закрывает InputStream объект.

Таким образом, достаточно только bReader.close ().

3
Anup Verma

Я опоздал, но:

BufferReader.Java:

public BufferedReader(Reader in) {
  this(in, defaultCharBufferSize);
}

(...)

public void close() throws IOException {
    synchronized (lock) {
        if (in == null)
            return;
        try {
            in.close();
        } finally {
            in = null;
            cb = null;
        }
    }
}
0
Дима Гашко

Вам Не нужно закрыть завернутый читатель/писатель.

Если вы взглянули на документы ( Reader.close() , Writer.close() ), вы увидите, что в Reader.close() написано:

Закрывает поток и освобождает любые системные ресурсы, связанные с ним.

Который просто говорит, что он "освобождает любые системные ресурсы связанные с ним". Даже если это не подтверждает ... это дает вам толчок, чтобы начать смотреть глубже. и если вы переходите к Writer.close(), он только утверждает, что закрывается сам.

В таких случаях мы обращаемся к OpenJDK , чтобы взглянуть на исходный код.

На BufferedWriter строка 265 вы увидите out.close(). Так что это не закрытие себя .. Это что-то еще. Если вы будете искать в классе вхождения «out», вы заметите, что в конструкторе в Line 87 что out является автором, который класс переносит, когда он вызывает другой конструктор, а затем назначает параметр out своей собственной переменной out. ,.

Так что .. как насчет других? Вы можете увидеть похожий код в BufferedReader Line 514 , BufferedInputStream Line 468 и InputStreamReader Line 199 . Других я не знаю, но этого должно быть достаточно, чтобы предположить, что они знают.

0
Omar Abdul'Azeez

Вам нужно только закрыть bufferedReader i.e reader.close (), и он будет работать нормально.

0
robust12

Начиная с Java 7 вы можете использовать оператор try-with-resources

try (BufferedReader br = new BufferedReader(new FileReader(path))) {
    return br.readLine();
}

Поскольку экземпляр BufferedReader объявлен в операторе try-with-resource, он будет закрыт независимо от того, завершается ли оператор try нормально или внезапно. Поэтому вам не нужно закрывать его самостоятельно в выражении finally. (Это также относится и к вложенным операторам ресурсов)

Это рекомендуемый способ работы с ресурсами, более подробную информацию смотрите в документации

0
Claudiu