Ява: Мне нужно закрыть все потоки? - PullRequest
1 голос
/ 18 мая 2011

У меня есть метод, который читает текст из файла; в зависимости от входного параметра может потребоваться декомпрессия:

public static String readText(File inFile, boolean compressed) {
    InputStream in = null;
    InputStreamReader isr = null;
    StringBuilder sb = new StringBuilder();//constant resizing is costly, so set the STRING_SIZE
    try {
        in = new FileInputStream(inFile);
        if (compressed) {
            in = new GZIPInputStream(in);
        }
        isr = new InputStreamReader(in);
        int length = 0;
        char[] cbuf = new char[8 * 1024];
        while ((length = isr.read(cbuf)) != -1) {
            sb.append(cbuf, 0, length);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            in.close();
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }
    return sb.toString();
}

Было предложено, чтобы я использовал InputStream таким образом, чтобы его было легче писать, и в итоге мне нужно было закрыть только одну вещь. Я все еще немного волнуюсь, это может вызвать утечку памяти. Итак, мой вопрос: кто-нибудь знает, в порядке ли код выше? Или мне нужно вернуться к дюжине потоков и закрыть их один за другим в блоке finally?

Большое спасибо.

Ответы [ 3 ]

3 голосов
/ 18 мая 2011

Да, закрытие внешнего потока / считывателя достаточно.

Однако в вашем коде есть еще одна потенциальная ошибка: new InputStreamReader(in) будет использовать кодировку платформы по умолчанию, которая зависит от региона / языковых настроек ОС.Вы должны указать кодировку текстового файла и явно использовать ее в конструкторе.

2 голосов
/ 18 мая 2011

Вот один пункт, который нужно добавить: посмотрите, является ли 'in' нулевым, прежде чем вызывать 'in.close ()', поскольку исключение может произойти без успешного выполнения первого присваивания.

Кроме того, полезно только перехватыватьвозможные исключения (например, IOException).Таким образом, если вы добавите больше кода, а среда IDE сообщит вам, что новый тип исключения не обработан, вы можете добавить соответствующий конкретный код, а не слышать об этом, потому что улов (Exception), который изначально был для IOException, также (неправильная обработка?) любой другой тип.

0 голосов
/ 20 июля 2012

Вот чистый способ Java 7, который работает для всего, что реализует AutoCloseable / Closeable:

try (InputStream in = compressed ?
                        new GZIPInputStream(new FileInputStream(inFile))
                      : new FileInputStream(inFile);
     InputStreamReader isr = new InputStreamReader(in))
{
    int length = 0;
    char[] cbuf = new char[8 * 1024];
    while ((length = isr.read(cbuf)) != -1) {
        sb.append(cbuf, 0, length);
    }
}
catch (Exception e) {
    e.printStackTrace();
}

Если вам интересно, что происходит, если при закрытии ресурса возникает исключение, прочитайте о getSuppressedExceptions (),Также был добавлен.

...