Подтвердить что ты не робот

Правильный способ закрыть OutputStream в Java?

Это кажется почти глупым, но что является самым надежным шаблоном для закрытия OutputStream? Прямо сейчас у меня есть что-то вроде следующего, которое просто кажется try-catch-finally-overkill:

private void writeContentsToFile(OutputStream ostream, Properties contents) {
    try {
        contents.store(ostream, "comments");
    }
    catch (IOException e) {
        throw new ResourceException("Failed to write contents", e);
    }
    finally {
        try {
            ostream.close();
        }
        catch (IOException e) { /* what can be done here anyway? */ }
    }
}

Зачем закрывать броски, проверенное исключение все еще остается загадкой для меня. Я могу создать метод-обертку, который делает блок close/catch, но если есть что-то уже там вроде FileUtil.closeFileAndThrowUncheckedException(), я бы хотел его использовать. Это становится более полезным, когда у вас много небольших проектов с большим количеством разработчиков; один из способов сделать это правильно.

4b9b3361

Ответ 2

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

Если вам не нравятся проверенные исключения (особенно для таких ошибок низкого уровня), завершите их как непроверенные. Или вы можете следовать соглашению Java, к лучшему или к худшему, и объявить IOException в вашем методе.

Ответ 3

Я думаю, что ваш путь - это "лучший" способ. Если close выдает исключение, вы действительно ничего не можете с этим поделать. Вероятно, это исключает пойманное исключение, потому что это может быть плохо, в зависимости от того, как оно используется. Если вам действительно нужно закрыть файл, который вы хотите принудительно применить. Если вы просто хотите использовать close для обработки ошибок, вы должны просто игнорировать исключение.

Ответ 4

Класс OputputStream имеет AutoCloseable. Следовательно, правильный способ использования экземпляра OutputStream - это блок try -with-resources, поэтому поток надежно закрывается при возникновении исключения. Не используйте блок try... finally: он будет работать неправильно для некоторых крайних случаев (случаев, которые требуют исключенного исключения). try -with-resources является рекомендуемым способом правильного закрытия всех ресурсов ввода-вывода, таких как поток.

    try (OutputStream output = ...) {
       ... // use the output stream
    } catch (IOException e) {
        ... // exception handling code
    }

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