Я только что поиграл с API файловой системы Java и нашел следующую функцию, используемую для копирования бинарных файлов. Первоначальный источник поступил из Интернета, но я добавил предложения try / catch / finally, чтобы быть уверенным, что в случае чего-то неправильного потоки буфера будут закрыты (и, следовательно, моя ОС освободит ресурсы) перед выходом из функции.
Я урезал функцию, чтобы показать шаблон:
public static void copyFile(FileOutputStream oDStream, FileInputStream oSStream) throw etc...
{
BufferedInputStream oSBuffer = new BufferedInputStream(oSStream, 4096);
BufferedOutputStream oDBuffer = new BufferedOutputStream(oDStream, 4096);
try
{
try
{
int c;
while((c = oSBuffer.read()) != -1) // could throw a IOException
{
oDBuffer.write(c); // could throw a IOException
}
}
finally
{
oDBuffer.close(); // could throw a IOException
}
}
finally
{
oSBuffer.close(); // could throw a IOException
}
}
Насколько я понимаю, я не могу поместить два close()
в предложение finally, потому что первый close()
вполне может бросить, а затем второй не будет выполнен.
Я знаю, что в C # есть шаблон Dispose , который обработал бы это с ключевым словом using
.
Я даже лучше знаю, что код C ++ был бы чем-то вроде (используя Java-подобный API):
void copyFile(FileOutputStream & oDStream, FileInputStream & oSStream)
{
BufferedInputStream oSBuffer(oSStream, 4096);
BufferedOutputStream oDBuffer(oDStream, 4096);
int c;
while((c = oSBuffer.read()) != -1) // could throw a IOException
{
oDBuffer.write(c); // could throw a IOException
}
// I don't care about resources, as RAII handle them for me
}
Я что-то упустил или мне действительно нужно создавать уродливый и раздутый код на Java только для обработки исключений в методе close()
буферизованного потока?
(Пожалуйста, скажите мне, что я где-то не прав ...)
РЕДАКТИРОВАТЬ: Это я или при обновлении этой страницы я видел, как вопрос и все ответы уменьшились на одну точку за пару минут? Кто-то слишком наслаждается, оставаясь анонимным?
РЕДАКТИРОВАТЬ 2: Макдауэлл предложил очень интересную ссылку, я чувствовал, что я должен был упомянуть здесь:
http://illegalargumentexception.blogspot.com/2008/10/java-how-not-to-make-mess-of-stream.html
РЕДАКТИРОВАТЬ 3: Следуя ссылке Макдауэлла, я наткнулся на предложение для Java 7 шаблона, аналогичного шаблону C #, используя шаблон: http://tech.puredanger.com/java7/#resourceblock. Моя проблема подробно описана. Видимо, даже с Java 7 do
проблемы остаются.