Я просто играл с 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()
мог бы сбрасывать, а затем второй не выполнялся.
Я знаю, что С# имеет шаблон Dispose, который обрабатывал бы это с помощью ключевого слова using
.
Я даже лучше знаю, что код на С++ был бы чем-то вроде (с использованием 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()
буферизованного потока?
(Пожалуйста, скажи мне, что я где-то не прав))
РЕДАКТИРОВАТЬ: Это я, или когда обновляю эту страницу, я видел, как вопрос, и все ответы уменьшились на один пункт за пару минут? Является ли кто-то слишком много себя переживающим, но при этом оставаясь анонимным?
EDIT 2: McDowell предложила очень интересную ссылку, которую я чувствовал, что должен был упомянуть здесь: http://illegalargumentexception.blogspot.com/2008/10/java-how-not-to-make-mess-of-stream.html
EDIT 3: Следуя ссылке McDowell, я применил предложение Java 7 шаблона, похожего на шаблон С#: http://tech.puredanger.com/java7/#resourceblock, Моя проблема явно описана. По-видимому, даже с Java 7 do
проблемы остаются.