Закрытие вложенного ридера - PullRequest
13 голосов
/ 05 февраля 2011

При чтении из текстового файла обычно создается FileReader, а затем вкладывается в BufferedReader. Кого из двух читателей мне следует закрыть, когда я закончу читать? Имеет ли это значение?

FileReader fr = null;
BufferedReader br = null;
try
{
    fr = new FileReader(fileName);
    br = new BufferedReader(fr);
    // ...
}
finally
{
    // should I close fr or br here?
}

Я немного параноик, когда дело доходит до безопасности исключений. Что происходит, когда конструктор BufferedReader выдает исключение? Закрывает ли он вложенный ридер? Или это гарантированно не скинуть?

Ответы [ 5 ]

10 голосов
/ 05 февраля 2011

Как правило, close() в самой внешней оболочке потока вызовет close() в обернутых потоках.Однако, если вы считаете, что конструктор, скорее всего, сгенерирует исключение, используйте интерфейс Closeable .

FileReader fr = new FileReader(fileName);
Closeable res = fr;
try {
    BufferedReader br = new BufferedReader(fr);
    res = br;
} finally {
    res.close();
}

Так что, даже если JVM исчерпала пространство кучи длябуфер и выдал ошибку, вы не пропустите дескриптор файла.

Для Java 7 и выше используйте try-with-resources:

try (FileReader fr = new FileReader(fileName);
    BufferedReader br = new BufferedReader(fr)) {
  // do work
}
0 голосов
/ 06 февраля 2011

Ничто не гарантировано, чтобы не бросать.Поскольку буфер выделен, он может выбросить OutOfMemoryError.Я обычно делю свой код на 2 раздела: собираю ресурсы и затем использую ресурсы.Каждый раздел обычно имеет уникальные потребности в очистке

Вот код для иллюстрации:

// Acquire resources section.

final FileReader fr = new FileReader( fileName );

BufferedReader br = null;

try
{
    br = new BufferedReader(fr);
}
finally
{
    if ( br == null )
    {
        // Note that you are closing the fr here
        fr.close( );
    }
}

// Use resources section
try
{
    // ... use br
}
finally
{
    // Now that br is safely constructed, just all its close
    br.close( );
}

И я согласен с вами, что нет ничего лучше, чем незаметно потерять обработчик файлов на долго работающем сервереприменение.

0 голосов
/ 05 февраля 2011

Если вы вызываете метод close BufferedReader, BufferedReader вызывает метод close FileReader.Таким образом, оба близких метода вызываются.Точнее, BufferedReader ничего не будет делать НО , вызывая метод close FileReader.Таким образом, это не имеет значения вообще.Хотя я думаю, что это хорошая практика, также вызывать метод close BufferedReader.

0 голосов
/ 05 февраля 2011

Закройте BufferedReader в блоке finally.

0 голосов
/ 05 февраля 2011

Достаточно закрыть только BufferedReader, потому что оно оборачивает FileReader. Если вы посмотрите на исходный код из BufferedReader, то увидите, что метод close закрывает завернутый поток.

...