Je m'attends à ce que le lecteur et le lecteur de fichiers mis en tampon se ferment et que les ressources soient libérées si l'exception est levée.
public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
try (BufferedReader br = new BufferedReader(new FileReader(filePath)))
{
return read(br);
}
}
Cependant, faut-il une clause catch
pour une fermeture réussie?
EDIT:
Le code ci-dessus dans Java 7 est-il équivalent au code ci-dessous pour 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;
}
C'est correct et il n'y a aucune exigence pour la clause catch
. Oracle Java 7 document indique que la ressource sera fermée peu importe du fait qu'une exception est réellement levée ou non.
Vous ne devez utiliser une clause catch
que si vous souhaitez réagir à l'exception. La clause catch
sera exécutée après la ressource est fermée.
Voici un extrait de tutoriel d'Oracle :
L'exemple suivant lit la première ligne d'un fichier. Il utilise une instance de BufferedReader pour lire les données du fichier. BufferedReader est une ressource qui doit être fermée une fois le programme terminé:
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.
... L'instance BufferedReader étant déclarée dans une instruction try-with-resource, elle sera fermée, que l'instruction try se termine normalement ou de manière abrupte (à la suite de la méthode BufferedReader.readLine qui lève une exception IO).
[~ # ~] éditer [~ # ~]
En ce qui concerne la nouvelle question modifiée:
Le code présent dans Java 6 exécute les blocs catch
, puis le bloc finally
. Les ressources restent donc potentiellement ouvertes dans le script catch
. bloc.
Dans Java 7, les ressources sont fermées avant le bloc catch
, de sorte que les ressources sont déjà fermées pendant le bloc catch
exécution. Ceci est documenté dans le lien ci-dessus:
Dans une instruction try-with-resources, tout blocage ou bloc final est exécuté après la fermeture des ressources déclarées.
Votre utilisation de try-with-resources fonctionnera bien dans ce cas particulier, mais ce n’est pas tout à fait correct. Vous ne devez pas enchaîner les ressources de cette manière car cela pourrait entraîner des surprises désagréables. Supposons que vous avez une taille de tampon 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);
}
}
Supposons que quelque chose a mal tourné et que vous avez fini avec sz
négatif. Dans ce cas, votre ressource de fichier (créée via new FileReader(filePath)
) sera [~ # ~] et non [~ # ~] fermée.
Pour éviter ce problème, vous devez spécifier chaque ressource séparément comme ceci:
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);
}
}
Dans ce cas, même si l'initialisation de br
échoue, file
est toujours fermé. Vous pouvez trouver plus de détails ici et ici .