Мне нужно закрыть() как 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();

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

Ответ 1

нет.

BufferedReader.close()

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

а также

FileReader.close()

делает.

Ответ 2

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

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
}

Ответ 3

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

Ответ 4

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

Ответ 5

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

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

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

Итак, достаточно только bReader.close().

Ответ 6

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

Ответ 7

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

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

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

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

Ответ 8

Я опаздываю, но:

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;
        }
    }
}

Ответ 9

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

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

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

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

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

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

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