Le problème revient très fréquemment sur le forum. Ne pouvant modifier le cours, et pour éviter de répéter tout le temps les mêmes choses, je me permets de créer cette discussion autour du sujet. Ce message sera amené à évoluer au cours du temps. N'hésitez pas à remonter tout point à corriger/améliorer/ajouter !
Méthode ancestrale (Java <= 6)
Il est possible d'obtenir le résultat sous forme de byte[] ou String, ici nous le lierons ligne par ligne afin de montrer toutes les étapes clés du traitement :
Tester la nullité des flux avant fermeture : si une erreur se produit lors de l'instanciation du 2nd flux, le 3ème sera null
Erreurs courantes :
new BufferedInputStream(new FileInputStream(...)) : si vous ne savez pas à quoi sert BufferedInputStream et que vous n'en avez pas l'utilité, alors ne l'utilisez pas !
new FileInputStream(new File("/path/to/file.ext")) : vous pouvez directement instancier le FileInputStream qui possède un constructeur prenant le chemin du fichier sous forme de String : new FileInputStream("/path/to/file.ext")
Critiques :
- Extrêmement verbeux : 32 lignes minimum
- Source d'erreur : 99% des développeurs ne savent pas gérer les close() proprement
- Multiple gestion des erreurs (duplication de code)
Java 7 introduit le try-with-resources permettant la gestion simple et sécurisée des flux. L'objectif est de déléguer aux compilateur tous les close() contenus dans le finally. Cela est similaire au with de Python ou using de .Net.
try (InputStream inputStream = new FileInputStream("/path/to/file.ext");
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) {
String line;
while ((line = bufferedReader.readLine()) != null)
doSomething(line);
} catch (IOException e) {
gestion(e);
}
Remarques :
Déclarer les flux séparément dans le try : les flux doivent être fermés 1 par 1. Si vous faites BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream("/path/to/file.ext"))) alors uniquement le BufferedReader sera fermé. Généralement les flux sont proprement implémentés : fermer l'englobeur fera appel à la fermeture de l'englobé. Mais cela n'est pas obligatoire, et donc on pourrait rencontrer une implémentation pouvant poser problème.
Méthodes utilitaires
Ces techniques permettent de lire des flux en 1 instruction, sans avoir à ré-implémenter le parcours du flux.
Il s'agit probablement de la bibliothèque la plus connue et la plus utilisée pour lire les flux. Elle propose, depuis la version 1.1 sortie en 2005 (il y a plus de 10 ans), les principales méthodes de lecture.
byte[] bytes = IOUtils.toByteArray(new FileInputStream("/path/to/file.ext"));
String content = IOUtils.toString(new FileInputStream("/path/to/file.ext"));
List<String> lines = IOUtils.readLines(new FileInputStream("/path/to/file.ext"));
for (Iterator it = IOUtils.lineIterator(new FileInputStream("/path/to/file.ext"), Charset.defaultCharset()); it.hasNext();) {
String line = it.next();
doSomething(line);
}
Remarques :
Ces méthodes lèvent une IOException en cas d'erreur, à gérer dans un catch.
Les flux ne sont pas fermés : il suffit d'appliquer un simple try-with-resources sur la méthode englobante. "Wherever possible, the methods in this class do not flush or close the stream. This is to avoid making non-portable assumptions about the streams' origin and further use. Thus the caller is still responsible for closing streams after use."
Voici donc le code minimal d'utilisation :
try (InputStream inputStream = new FileInputStream("/path/to/file.ext")) {
YYY res = IOUtils.XXX(inputStream);
} catch (IOException e) {
gestion(e);
}
Non-blocking I/O (Java 7)
Le nouveau package java.nio a été introduit afin de remplacer l'ancienne API java.io, proposant de nouvelles fonctionnalités de lecture de fichiers. Elle introduit notamment les classes utilitaires Files et Paths.
Cette bibliothèque de Google propose également de très nombreuses fonctionnalités, dont la gestion des flux.
Les fonctionnalités sont proches de celle d'Apache.
Autres fonctionnalités
Les flux de sortie (OutputStream), ainsi que la copie de flux (InputStream > OutputStream) sont aussi des opérations fastidieuses, qui pourront être effectuées aussi simplement avec les mêmes bibliothèques citées précédemment. Je vous laisse parcourir les différentes méthodes de votre côté.
- Edité par Pinguet62 24 avril 2016 à 16:23:09
Angular 2 est l'avenir, jQuery c'est de la merde !!! - Java 8 c'est l'an 2016+ (programmez en 1 ligne)
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.