Безопасно ли использовать Apache commons-io IOUtils.closeQuietly?
Этот код
BufferedWriter bw = new BufferedWriter(new FileWriter("test.txt"));
try {
bw.write("test");
} finally {
IOUtils.closeQuietly(bw);
}
безопасно или нет? Насколько я понимаю, когда мы закрываем BufferedWriter, он будет выгружать свой буфер в базовый поток и может выйти из строя из-за ошибки. Но IOUtils.closeQuietly API говорит, что любые исключения будут проигнорированы.
Возможно ли, что потеря данных останется незамеченной из-за IOUtils.closeQuietly?
Ответы
Ответ 1
Код должен выглядеть так: javadoc closeQuietly()
:
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter("test.txt"));
bw.write("test");
bw.flush(); // you can omit this if you don't care about errors while flushing
bw.close(); // you can omit this if you don't care about errors while closing
} catch (IOException e) {
// error handling (e.g. on flushing)
} finally {
IOUtils.closeQuietly(bw);
}
closeQuietly()
не предназначен для общего использования, а не для вызова close()
непосредственно в Closable. Его предназначенный прецедент предназначен для обеспечения закрытия внутри блока finally - все необходимые обработки ошибок необходимо выполнить до этого.
Это означает, что если вы хотите отреагировать на Исключения во время вызова close()
или flush()
, тогда вы должны обработать его обычным способом. Добавление closeQuietly()
в ваш окончательный блок просто обеспечивает закрытие, например. когда сбой сброса и закрытие не было вызвано в try-block.
Ответ 2
Это безопасно, пока ваше приложение не заботится о том, удалось ли писать без ошибок. Если ваше приложение должно обрабатывать ошибки записи, это небезопасно, так как буферизованные данные, сброшенные на закрытии, могут быть потеряны и ошибка проглатывается.
Ответ 3
Это возможно в теории, но я не могу сказать, что я когда-либо видел близко() терпеть неудачу. Обычно fail fast означает, что предыдущие операции ввода-вывода, такие как открытие файла, будут сбой первым. Вы можете написать закрытие, которое не игнорирует IOExceptions, но это может скрыть истинную причину исключения, если это не удалось в блоке try/catch.
Что вы хотите, это что-то вроде следующего (что в большинстве случаев является чрезмерным)
try {
// write to bw.
bw.close(); // throw IOException if an error occurs.
} finally {
// don't clobber a previous IOException
IOUtils.closeQuietly(bw);
}