2011-08-28 15 views
27

Quiero cerrar mi secuencia en el bloque finally, pero arroja un IOException por lo que parece que tengo que anidar otro bloque try en mi bloque finally para cerrar la secuencia. ¿Es esa la forma correcta de hacerlo? Parece un poco torpe.java try finally block to close stream

Aquí está el código:

public void read() { 
    try { 
     r = new BufferedReader(new InputStreamReader(address.openStream())); 
     String inLine; 
     while ((inLine = r.readLine()) != null) { 
      System.out.println(inLine); 
     } 
    } catch (IOException readException) { 
     readException.printStackTrace(); 
    } finally { 
     try { 
      if (r!=null) r.close(); 
     } catch (Exception e){ 
      e.printStackTrace(); 
     } 
    } 


} 
+0

posible duplicado de [¿Existe una preferencia por bloques anidados try/catch?] (Http://stackoverflow.com/questions/183499/is-there-a-preference-for-nested-try-catch-blocks) –

Respuesta

19

Parece un poco torpe.

Es. Al menos la prueba de java7 con recursos corrige eso.

Pre Java7 se puede hacer una función closeStream que se lo traga:

public void closeStream(Closeable s){ 
    try{ 
     if(s!=null)s.close(); 
    }catch(IOException e){ 
     //Log or rethrow as unchecked (like RuntimException) ;) 
    } 
} 

O poner la intenta ... finalmente dentro del intento de captura:

try{ 
    BufferedReader r = new BufferedReader(new InputStreamReader(address.openStream())); 
    try{ 

     String inLine; 
     while ((inLine = r.readLine()) != null) { 
      System.out.println(inLine); 
     } 
    }finally{ 
     r.close(); 
    } 
}catch(IOException e){ 
    e.printStackTrace(); 
} 

Es más detallado y una excepción en finalmente se ocultará uno en el intento, pero semánticamente está más cerca del try-with-resources introducido en Java 7.

+0

Fui con el segundo enfoque ya que es más limpio y legible. Esto es realmente importante, ya que queremos evitar fugas de memoria. – Akshay

8

Sí, es torpe, feo y confuso. Una posible solución es usar Commons IO que ofrece un método closeQuietly.

Hay una serie de preguntas en la columna "Relacionadas" a la derecha de esta página que en realidad son duplicados, le aconsejo que busque otras formas de resolver este problema.

2

Su enfoque dentro de finalmente es correcto. Si el código que usted llama en un bloque finally puede arrojar una excepción, asegúrese de manejarlo o registrarlo. Nunca dejes que salga burbujeante del bloque final.

Dentro del bloque catch se está tragando la excepción, lo que no es correcto.

Gracias ...

32

Además, si usted está utilizando Java 7, se puede utilizar un try-with-resources statement:

try(BufferedReader r = new BufferedReader(new InputStreamReader(address.openStream()))) { 
    String inLine; 
    while ((inLine = r.readLine()) != null) { 
     System.out.println(inLine); 
    } 
} catch(IOException readException) { 
    readException.printStackTrace(); 
}   
20

En Java 7 se puede hacer esto ...

try (BufferedReader r = new BufferedReader(...)){ 
    String inLine; 
    while ((inLine = r.readLine()) != null) { 
      System.out.println(inLine); 
    } 
} catch(IOException e) { 
    //handle exception 
} 
  • Declarar una variable en el bloque try requiere que implemente AutoCloseable.
  • Declarar una variable en el bloque try también limita su alcance al bloque try .
  • Cualquier variable declarada en el bloque try tendrá automáticamente close() llamado cuando se cierre el bloque try.

Se llama Try with resources statement.

5

Como la respuesta que menciona la biblioteca Commons IO, Google Guava Libraries tiene un método de ayuda similar para cosas que son java.io.Closeable. La clase es com.google.common.io.Closeables.La función que está buscando se llama de forma similar como Commons IO: closeQuietly().

O usted podría rodar su propia para cerrar un montón así: Closeables.close (closeable1, closeable2, closeable3, ...):

import java.io.Closeable; 
import java.util.HashMap; 
import java.util.Map; 

public class Closeables { 
    public Map<Closeable, Exception> close(Closeable... closeables) { 

    HashMap<Closeable, Exception> exceptions = null; 

    for (Closeable closeable : closeables) { 
    try { 
     if(closeable != null) closeable.close(); 
    } catch (Exception e) { 
     if (exceptions == null) { 
      exceptions = new HashMap<Closeable, Exception>(); 
     } 
     exceptions.put(closeable, e); 
     } 
    } 

    return exceptions; 
    } 
} 

Y que incluso devuelve un mapa de las excepciones que eran arrojado o nulo si no hubiera ninguno.

+0

A quien haya votado negativamente mi respuesta, ¿podría explicar por qué para que yo pueda aprender de ello? –

+0

Te votaré de vuelta para que salga bien. Guava es una gran biblioteca – thaspius

0
public void enumerateBar() throws SQLException { 
    Statement statement = null; 
    ResultSet resultSet = null; 
    Connection connection = getConnection(); 
    try { 
     statement = connection.createStatement(); 
     resultSet = statement.executeQuery("SELECT * FROM Bar"); 
     // Use resultSet 
    } 
    finally { 
     try { 
      if (resultSet != null) 
       resultSet.close(); 
     } 
     finally { 
      try { 
       if (statement != null) 
        statement.close(); 
      } 
      finally { 
       connection.close(); 
      } 
     } 
    } 
} 

private Connection getConnection() { 
    return null; 
} 

source. Esta muestra fue útil para mí.

+0

gracias. actualizado. –

Cuestiones relacionadas