Зачем мне заботиться об исключениях IOException, когда файл закрыт?
Я видел такие вещи в коде Java довольно часто...
try
{
fileStream.close();
}
catch (IOException ioe)
{
/* Ignore. We do not care. */
}
Это разумно или кавалер?
Когда бы я заботился о том, что закрытие файла не удалось? Каковы последствия игнорирования этого исключения?
3 ответа
Я бы как минимум зарегистрировал исключение.
Я видел, как это иногда случалось, если попытка закрыть файл не удалась из-за невозможности сброса данных. Если вы просто проглотите исключение, вы потеряете данные, не осознавая этого.
В идеале, вам, вероятно, следует проглотить исключение, если вы уже находитесь в контексте другого исключения (т.е. вы находитесь в блоке finally, но из-за другого исключения, а не после завершения блока try), но выбросить его, если ваша операция выполняется иначе успешный. К сожалению, это несколько уродливо, чтобы разобраться:(
Но да, вы должны хотя бы войти в систему.
Вам было бы все равно, если close()
Метод сбрасывает записанное содержимое из буфера в файловую систему, и это не удается. например, если файл, в который вы пишете, находится в удаленной файловой системе, которая стала недоступной.
Обратите внимание, что выше ре. сброс применяется ко всем выходным потокам, а не только к файлам
Наиболее распространенными проблемами close() являются нехватка дискового пространства или, как упомянул Брайан, удаленный поток, который потерял свою актуальность.
НОТА:
Вы должны действительно увидеть что-то вроде (примечание: я не проверял это)
SomeKindOfStream stream = null;
Throwable pending = null;
try {
stream = ...;
// do stuff with stream
} catch (ThreadDeath t) {
// always re-throw thread death immediately
throw t;
} catch (Throwable t) {
// keep track of any exception - we don't want an exception on
// close() to hide the exceptions we care about!
pending = t;
} finally {
if (stream != null)
try {
stream.close();
} catch (IOException e) {
if (pending == null)
pending = e;
}
}
if (pending != null) {
// possibly log - might log in a caller
throw new SomeWrapperException(pending);
// where SomeWrapperException is unchecked or declared thrown
}
}
Почему все это?
Помните, что Java может отслеживать только одно "ожидающее" исключение за раз. Если тело основного блока try выдает исключение, а метод close() в finally выдает исключение, единственное, о чем вы будете знать, - это close().
Вышеуказанная структура делает следующее:
- Следите за любым бросаемым броском в теле попытки
- В случае, если это исключение - смерть потока, немедленно отбросьте его!
- При закрытии, если у нас нет ожидающего исключения, отследите исключение закрытия; в противном случае ранее созданное исключение должно отслеживаться. (В этом случае вам, вероятно, следует попытаться записать ошибку close())
- В конце, если есть ожидающее исключение, разберитесь с ним. Я обычно оборачиваю это и перебрасываю это. Лично я использую непроверенную оболочку, поэтому мне не нужно, чтобы все вызывающие в цепочке вызовов объявляли броски.
Чтобы выполнить вышеизложенное, я обычно использую шаблон метода шаблона для создания управления исключениями, а затем перезаписываю метод doWork(), который является телом try.