Ваш код, который вызывает InputStream.close()
или OutputStream.close()
, является кодом высокого уровня, который делегирует классу InputStream
или OutputStream
более низкого уровня для выполнения вычислений высокого уровня.
Вызывать ли исключение
У вас есть только 3 варианта действий.
Последние две опции похожи в том, что ваш код вызывает исключение. Так что этот вопрос на самом деле является частным случаем вопроса , когда мой код должен выдать исключение . правильный ответ на этот вопрос в этом контексте таков: если и только если альтернатива состоит в том, чтобы не выполнить условие поста вашего кода или сохранить инвариант вашего кода . Условия публикации определяют, что должен делать ваш метод. Инварианты указывают характеристики класса.
Итак, вам нужно спросить себя, не исключает ли исключение close()
метод вашего , делающий то, что должен делать.
- Если это не мешает вашему методу выполнять свою работу, правильное решение - проглотить исключение. Несмотря на то, что многие скажут вам.
- Если бросок
close()
не позволяет вашему методу выполнить свою работу, и метод может выбросить IOException
, вы ничего не можете сделать, , просто позволяя исключению распространяться вверх .
- Если
close()
запрещает вашему методу выполнять свою работу, но метод может не выдавать IOException
, вы должны перехватить IOException
и перебросить его как другой класс исключения, записав IOException
как причину выброшенное исключение.
Я не знаю обстоятельств, при которых InputStream.close()
, вызывающее исключение, может помешать успешному вычислению. Этот вызов close()
естественно происходит после того, как вы закончили читать любые интересующие вас данные.
Выходные потоки, однако, могут буферизовать данные для записи в место назначения вывода, либо внутри (в коде Java), либо на более низком уровне (в операционной системе). Поэтому вы не можете быть уверены, что операции записи в выходной поток действительно привели к реальному выводу, пока OutputStream.close()
не будет успешно возвращен ( без , исключая исключение). Поэтому вы должны рассматривать исключение, выдаваемое OutputStream.close()
, как ошибку записи.
Ваш метод отвечает за поддержку своих инвариантов. Иногда это потребует операции очистки или отката, если close()
выдает исключение. Вы должны поместить код для этого в предложение catch
или finally
для IOException
, даже если вы хотите, чтобы исключение распространялось вверх. Если вы используете предложение catch и хотите распространить его, вам придется выбросить его заново.
Регистрировать ли исключение
Некоторые люди посоветуют вам зарегистрировать исключение . Это почти всегда плохой совет. Сообщения журнала являются частью пользовательского интерфейса вашей программы. По сути, вы всегда должны задавать себе вопрос, регистрировать ли вообще что-нибудь , потому что бесполезное словоблудие может отвлекать и сбивать с толку пользователей, читающих ваш файл журнала («пользователи» включают системных администраторов). Каждое зарегистрированное сообщение должно быть для какой-то полезной цели. Каждый должен предоставить информацию, которая помогает пользователю принимать решения .
Сообщение о том, что close()
не удалось, редко полезно. Как это может помочь пользователю принять решение? Если исключение не помешало вашему методу выполнить свою работу, проблем нет, и никаких действий со стороны пользователя не требуется. Если вашей программе не удалось close()
поток, и что является проблемой, чем может помочь пользователь?
Код низкого уровня обычно вообще не отвечает за ведение журнала.Вместо этого он выполняет абстрактные операции, сообщая о сбоях компонентам более высокого уровня, создавая исключения.Код, закрывающий поток, как правило, имеет довольно низкий уровень, поэтому код, который обнаруживает, что close()
является слишком низким уровнем, чтобы вести какую-либо запись.
Конкретный факт сбоя close()
редко полезен.Что может быть полезно, так это знание, что абстрактная операция, которую должен выполнить ваш метод, не удалась.Это можно сделать, если код более высокого уровня перехватит все ожидаемые исключения и сообщит о сбое операции, вместо того, чтобы ваш метод точно сообщал, что «сбой при закрытии».