Pregunta ¿Estoy usando Java 7 try-with-resources correctamente?


Estoy esperando que el lector y el lector de archivos almacenados en el búfer se cierren y los recursos se liberen si se lanza la excepción.

public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
    try (BufferedReader br = new BufferedReader(new FileReader(filePath)))
    {
        return read(br);
    } 
}

Sin embargo, ¿existe un requisito de tener un catch cláusula para el cierre exitoso?

EDITAR:

Básicamente, el código anterior en Java 7 es equivalente al siguiente para Java 6:

public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{

    BufferedReader br = null;

    try
    {
        br = new BufferedReader(new FileReader(filePath));

        return read(br);
    }
    catch (Exception ex)
    {
        throw ex;
    }
    finally
    {
        try
        {
            if (br != null) br.close();
        }
        catch(Exception ex)
        {
        }
    }

    return null;
}

76
2017-07-15 09:32


origen


Respuestas:


Es correcto y no hay ningún requisito para catch cláusula. Oracle java 7 doc dice que el recurso se cerrará independientemente de si se ha lanzado una excepción o no.

Deberías usar un catch cláusula solo si desea reaccionar ante la excepción. los catch cláusula será ejecutada después el recurso está cerrado.

Aquí hay un fragmento de Tutorial de Oracle:

El siguiente ejemplo lee la primera línea de un archivo. Utiliza una   instancia de BufferedReader para leer datos del archivo. BufferedReader   es un recurso que debe cerrarse después de que el programa haya terminado   eso:

static String readFirstLineFromFile(String path) throws IOException {
    try (BufferedReader br =
                   new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }
} // In this example, the resource declared in the try-with-resources statement is a BufferedReader.

... Porque la instancia de BufferedReader se declara en una   declaración try-with-resource, se cerrará independientemente de si   la instrucción try se completa de forma normal o abrupta (como resultado de   método BufferedReader.readLine lanzando una IOException).

EDITAR

En cuanto a la nueva pregunta editada:

El código en Java 6 ejecuta el catch y luego el finally bloquear. Esto hace que los recursos aún estén potencialmente abiertos en el catch bloquear.

En la sintaxis de Java 7, los recursos están cerrados antes de el catch bloquear, por lo que los recursos ya están cerrados durante el catch ejecución de bloque. Esto está documentado en el enlace de arriba:

En una instrucción try-with-resources, se ejecuta cualquier bloqueo catch o finally   después de que los recursos declarados hayan sido cerrados.


94
2017-07-15 09:40



Su uso de try-with-resources funcionará bien en este caso particular, pero no es del todo correcto en general. No deberías encadenar recursos así porque pueden generar sorpresas desagradables. Supongamos que tiene un tamaño de búfer variable:

public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
    int sz = /* get buffer size somehow */
    try (BufferedReader br = new BufferedReader(new FileReader(filePath), sz))
    {
        return read(br);
    } 
}

Supongamos que algo salió mal y terminaste con sz siendo negativo En este caso, su recurso de archivo (creado a través de new FileReader(filePath)) será NO estar cerrado.

Para evitar este problema, debe especificar cada recurso por separado de esta manera:

public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
    int sz = /* get buffer size somehow */
    try (FileReader file = new FileReader(filePath);
         BufferedReader br = new BufferedReader(file, sz))
    {
        return read(br);
    } 
}

En este caso, incluso si la inicialización de br falla file todavía se cierra Puedes encontrar más detalles aquí y aquí.


64
2018-01-25 09:37