Eclipse предупреждает о потенциальной утечке ресурсов, хотя у меня есть блок finally, который закрывает самый внешний поток, что мне не хватает?

1

есть причина, по которой Eclipse дает мне следующее предупреждение о утечке ресурсов: утечка ресурсов: "br" никогда не закрывается "? Код, о котором я говорю, находится внизу этой публикации.

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

  • res будет только null, если конструктор FileInputStream бросил, и поэтому ничего не нужно закрывать
  • res будет входным потоком, если конструктор InputStreamReader выбрасывает (например, некорректную строку кодирования), а затем только входной поток должен быть закрыт так нормально
  • и т.д...

Так что я пропущу? Или это может быть ошибка затмения?

С уважением!

С.

public static String fileToString(String fileName, String encoding) throws IOException {
    InputStream is;
    InputStreamReader isr;
    BufferedReader br;
    Closeable res = null;
    try {
        is = new FileInputStream(fileName);
        res = is;
        isr = new InputStreamReader(is, encoding);
        res = isr;
        br = new BufferedReader(isr);
        res = br;
        StringBuilder builder = new StringBuilder();
        String line = null;
        while ((line = br.readLine()) != null) {
            builder.append(line);
            builder.append(LS);
        }
        return builder.toString();
    } finally {
        if (res != null) {
            res.close();
        }
    }
}
  • 1
    Вроде все в порядке. Я думаю, что затмение просто не может правильно проанализировать код.
Теги:
streamreader

1 ответ

5
Лучший ответ

Возможно, Eclipse просто не понимает, что вы перетасовываете с переменной res.

Я рекомендую использовать оператор try-with-resources (доступный на Java 7 и выше, так что три с половиной года), он значительно упрощает такие типы цепочек:

public static String fileToString(String fileName, String encoding) throws IOException {

    try (
        InputStream is = new FileInputStream(fileName);
        InputStreamReader isr = new InputStreamReader(is, encoding);
        BufferedReader br = new BufferedReader(isr)
    ) {
        StringBuilder builder = new StringBuilder();
        String line = null;
        while ((line = br.readLine()) != null) {
            builder.append(line);
            builder.append(LS);
        }
        return builder.toString();
    }
}

Если вы не можете использовать примерочный с-ресурсами, вы, вероятно, хотите что - то вроде Apache Commons IOUtils класса closeQuietly методов (либо буквально, что один или самостоятельно), а не шаркая res вокруг, что неудобно читать, и я полагаю, склонные к вопросы обслуживания.

Использование IOUtils может выглядеть так:

public static String fileToString(String fileName, String encoding) throws IOException {
    InputStream is = null;
    InputStreamReader isr = null;
    BufferedReader br = null;

    try {
        is = new FileInputStream(fileName);
        isr = new InputStreamReader(is, encoding);
        br = new BufferedReader(isr)
        StringBuilder builder = new StringBuilder();
        String line = null;
        while ((line = br.readLine()) != null) {
            builder.append(line);
            builder.append(LS);
        }
        br.close();
        return builder.toString();
    }
    finally {
        IOUtils.closeQuietly(br, isr, is);
    }
}

Обратите внимание, как я использую обычное close в try, но затем завершаю finally очистку.

Но попробовать-с-ресурсами - лучший ответ, поскольку он более краток и перехватывает новые (иш) "подавленные исключения".


Боковое примечание: нет причин для инициализации line = null, вы назначаете ее на следующей строке.

Замечание 2: Если файл, вероятно, будет иметь какой-либо размер, подумайте над тем, насколько он заблаговременно, и задайте емкость StringBuilder в конструкторе. StringBuilder емкость StringBuilder - 16, поэтому файл с несколькими сотнями байт включает несколько перераспределений внутреннего буфера StringBuilder.

  • 1
    Спасибо за ваш ответ (помеченный как принятый), а также за соответствующий совет, касающийся попыток с ресурсами, строителями строк и ненужной нулевой инициализацией!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню