Я просто играл с API-интерфейсом файловой системы Java и пришел со следующей функцией, используемой для копирования двоичных файлов. Исходный источник пришел из Интернета, но я добавил предложения try/catch/finally, чтобы убедиться, что, если что-то не так, буферизованные потоки будут закрыты (и, следовательно, освобождены мои операционные системы), прежде чем выйти из функции.RAII на Java ... это утилизация ресурсов всегда так безобразно?
я урезана функцию, чтобы показать картину:
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()
в наконец статье, потому что первая close()
вполне может бросить, и затем второй не будет выполнен.
Я знаю, что у C# есть 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: Это я, или при обновлении этой страницы, я увидел, как этот вопрос и все ответы снизился на один пункт в пара минут? Кто-то слишком любит себя, оставаясь анонимным?
EDIT 2: Макдауэлл предложил очень интересную ссылку, я чувствовал, что я должен был упомянуть здесь: http://illegalargumentexception.blogspot.com/2008/10/java-how-not-to-make-mess-of-stream.html
EDIT 3: После ссылки Макдауэлл, я упал на предложение о Java 7 узора аналогичной C# с использованием шаблона: http://tech.puredanger.com/java7/#resourceblock. Моя проблема явно описана. По-видимому, даже с Java 7 do
проблемы остаются.
Извинения за мой ошибочный ответ. Я не был уверен, действительно ли вы пытаетесь понять, как сделать RAII на Java, или просто не знал, как обычно копировать данные из входного потока в выходной поток в Java. – Alexander 2008-10-11 16:58:52
Нет проблем ... Дело в том, что я тоже не знал, как сделать чистую и эффективную копию ... :-p ... – paercebal 2008-10-12 17:47:12
Вы можете сохранить 8 строк кода в первом листинге и 2 строки в секунду если вы будете использовать соглашение Java-кода. В этом случае этот код будет не таким уродливым. – msangel 2013-03-04 02:56:52