2011-06-07 12 views
21

Esto parece casi tonto, pero ¿cuál es el patrón más confiable a seguir al cerrar un OutputStream? Ahora mismo tengo algo así como lo siguiente, que sólo parecen ser try-catch-finally-exageración:¿La forma correcta de cerrar un OutputStream en Java?

private void writeContentsToFile(OutputStream ostream, Properties contents) { 
    try { 
     contents.store(ostream, "comments"); 
    } 
    catch (IOException e) { 
     throw new ResourceException("Failed to write contents", e); 
    } 
    finally { 
     try { 
      ostream.close(); 
     } 
     catch (IOException e) { /* what can be done here anyway? */ } 
    } 
} 

¿Por qué cerrar lanza una excepción comprobada sigue siendo un misterio para mí. Puedo crear el método de envoltura que hace el bloque de cerrar/capturar, pero si hay algo que ya existe, como FileUtil.closeFileAndThrowUncheckedException(), me gustaría usarlo. Esto se vuelve un poco más útil cuando tienes muchos proyectos más pequeños con muchos desarrolladores; una forma de hacerlo bien

+1

close() podría escribir datos. si, por ejemplo, una corriente subyacente almacena datos, close() vaciará los datos, y eso podría fallar por la misma razón que una llamada de escritura podría fallar (en el caso de, por ejemplo, sockets, es posible que close() pueda señalar una falla de uno de los también escribe llamadas) – nos

+0

Considera usar un escritor en lugar de trabajar directamente con la transmisión. Los escritores ofrecen muchas comodidades si usa una adaptada a la tarea. Por ejemplo, al almacenar sus propiedades con un 'BufferedWriter' sería una buena opción. Si miras el código fuente, verás que se vacía y cierra la transmisión, aunque igual tendrás que lidiar con la IOException "extra". – Paul

+0

@Paul: Normalmente lo hago, pero utilicé el OutputStream para este caso solo como un ejemplo rápido. –

Respuesta

19

Si está utilizando Apache Commons, entonces IOUtils.closeQuietly() hace el trabajo muy bien. Ver http://commons.apache.org/proper/commons-io/javadocs/api-1.4/org/apache/commons/io/IOUtils.html#closeQuietly(java.io.OutputStream)

+0

¿Cómo extrañé eso? Pensé que revisé IOUtils. Le daré tiempo a la pregunta para obtener más comentarios, pero esto está muy al tanto. –

+0

Cuando solía implementar esto, solía envolver la IOException con una RuntimeException y simplemente lanzarla de nuevo, pero closeQuietly realmente está tragando la excepción. ¿Cual es mejor? – Ring

0

Creo que su camino es la "mejor" manera. Si close arroja una excepción, de hecho no puedes hacer nada al respecto. Esto probablemente arroja una excepción atrapada porque podría ser malo, dependiendo de cómo se use. Si realmente necesita cerrar un archivo, le gustaría aplicarlo. Si solo quiere usar close para el manejo de errores, simplemente debe ignorar la excepción.

0

No creo que la excepción deba tragarse. La persona que llama se deja engañar al creer que el contenido se escribió con éxito. La excepción debería propagarse hacia arriba.

Si no le gustan las excepciones comprobadas (especialmente para los errores de nivel bajo), envuélvalas como desmarcadas. O puede seguir la convención de Java, para bien o para mal, y declarar IOException en su método.

Cuestiones relacionadas