Java dispose d’un Garbage Collector. Celui-ci, très pratique, ne fonctionne que pour les objets propres à la JVM, et pas quand une ressource externe entre en jeu, notamment les entrées/sorties vers les fichiers. Si vous ne faites pas attention à ce dernier point, c’est une erreur TooManyOpenFiles
assurée, avec probable redémarrage de la JVM à la clef si vous n’avez pas activé JMX.
Malheureusement pour nous, fermer ses flux fichiers en Java est moins trivial qu’il n’y paraît…
Débloque les + belles offres tech en 10 mins
Dans la suite on joue uniquement avec des Stream en entrée, mais en fait la même chose s’applique pour ceux en sortie comme les OutputStream
.
Le code suivant est complètement cassé :
try {
InputStream is = new FileInputStream(...);
InputStreamReader ir = new InputStreamReader(is);
BufferedReader br = new BufferedReader(ir);
// ...
br.close();
ir.close();
is.close();
] catch (IOException e) {
e.printStackTrace();
}
La raison ne vient pas de la gestion d’exception, mais bien de la gestion des flux. En effet si une erreur survient entre l’ouverture des flux et leur fermeture, rien ne garantit que ces derniers seront correctement fermés, ou du moins pas avant le prochain passage du GC qui peut être dans… longtemps. Dès lors on court là encore droit à l’erreur TooManyOpenFiles
.
La bonne manière de faire est hélas bien plus verbeuse. Il s’agit d’écrire le code suivant :
InputStream is = null;
InputStreamReader ir = null;
BufferedReader br = null;
try {
is = new FileInputStream(...);
ir = new InputStreamReader(is);
br = new BufferedReader(ir);
// ...
] catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {}
}
if (ir != null) {
try {
ir.close();
} catch (IOException e) {}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {}
}
}
Alors oui c’est lourd, ultra verbeux, pénible, vous pouvez dire ce que vous voulez. Dans la librairie commons-io
d’Apache IOUtils.closeQuietly peut améliorer quelque peu le code au niveau de la fermeture des fichiers mais quand même, ça reste lourd.
C’est d’ailleurs une des raisons qui explique pourquoi beaucoup de gens ne gèrent pas correctement les flux en Java.
Java 7 introduit un nouveau concept dénommé try-with-resource
. Pour en profiter il suffit que votre objet implémente l’interface Closeable, ce qui est justement le cas de nos Stream.
Dès lors le code vu plus haut se traduit de la manière suivante :
try (InputStream is = new FileInputStream(...);
InputStreamReader ir = new InputStreamReader(is);
BufferedReader br = new BufferedReader(ir);) {
// ...
] catch (IOException e) {
e.printStackTrace();
}
On remarque notamment qu’il n’est plus nécessaire d’invoquer manuellement la méthode close()
puisque le try-with-resource s’en charge pour nous. Ca allège quand même violemment le code. Cela dit il est important d’ouvrir les streams un par un et pas en appels imbriqués du type new BufferedReader(new InputStreamReader(new FileInputStream(...)))
. En effet, si l’ouverture du BufferedReader
venait à échouer le FileInputStream
ne serait pas fermé !
Mais bon, force est d’améliorer que ça améliorer nettement la lisibilité du code.
Débloque les + belles offres tech en 10 mins
Cet article vous a plu ? Vous aimerez sûrement aussi :
Julien
Moi c’est Julien, ingénieur en informatique avec quelques années d’expérience. Je suis tombé dans la marmite étant petit, mon père avait acheté un Apple – avant même ma naissance (oui ça date !). Et maintenant je me passionne essentiellement pour tout ce qui est du monde Java et du système, les OS open source en particulier.
Au quotidien, je suis devops, bref je fais du dév, je discute avec les opérationnels, et je fais du conseil auprès des clients.
Les maladies inflammatoires chroniques de l’intestin ou "MICI" sont invisibles, mais leurs impacts sur la…
Depuis l'été, j'ai un Pixel qui intègre à la fois un TPU (Tensor Processing Unit)…
On se retrouve dans un nouvel article avec toutes les infos sur cette nouvelle saison…
Pourquoi l’inclusion numérique est essentielle : le point avec Mathieu Froidure. Dans un monde de…
Elles sont passées où les femmes dans la tech ? Entre le manque de représentation…
View Comments
On peut maintenant utiliser Files.newBufferedWriter(..), c'est beaucoup plus pratique ! :)