Acabo de jugar con la API del sistema de archivos Java, y obtuve la siguiente función, que se usa para copiar archivos binarios. La fuente original provino de la Web, pero agregué cláusulas try/catch/finally para asegurarme de que, en caso de que ocurriera algo mal, se cerraran los Buffer Streams (y, por lo tanto, mis recursos de SO liberados) antes de abandonar la función.RAII en Java ... ¿la eliminación de recursos siempre es tan desagradable?
I ajustado abajo la función de mostrar el patrón:
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
}
}
Por lo que yo entiendo, no puedo poner los dos close()
en la cláusula finalmente, porque la primera close()
bien podría lanzar, y luego, la segundo no se ejecutará.
Sé que C# tiene el Eliminar el patrón que hubiera manejado esto con la palabra clave using
.
siquiera sé mejor un código C++ habría sido algo así como (usando una API similar a Java):
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
}
me falta algo, o hacer que realmente tiene que producir código feo e hinchado en Java solo para manejar excepciones en el método close()
de un flujo en búfer?
(Por favor, dime que estoy equivocado en alguna parte ...)
EDIT: ¿Soy yo, o cuando la actualización de esta página, vi la pregunta y todas las respuestas se redujo en un punto de una ¿un par de minutos? ¿Alguien se divierte demasiado mientras se mantiene en el anonimato?
EDIT 2: McDowell le mostrará un enlace muy interesante me sentí que tenía que mencionar aquí: http://illegalargumentexception.blogspot.com/2008/10/java-how-not-to-make-mess-of-stream.html
Datos 3: siguiente enlace de McDowell, que cayeron sobre una propuesta para Java 7 de un patrón similar al de el patrón de uso de C#: http://tech.puredanger.com/java7/#resourceblock. Mi problema está explícitamente descrito. Aparentemente, incluso con Java 7 do
, los problemas persisten.
Disculpas por mi respuesta equivocada. No estaba seguro de si realmente te gustaba descifrar una forma de hacer RAII en Java, o simplemente no sabía cómo uno normalmente copia los datos de un flujo de entrada en un flujo de salida en Java. – Alexander
No hay problema ... El hecho es que tampoco sabía cómo hacer una copia limpia y eficiente ... :-p ... – paercebal
Puede guardar 8 líneas de código en el primer listado y 2 líneas en el segundo listando si usarás la convención del código java. En ese caso, este código no será tan feo. – msangel