Ce td/tp fait un rappel sur la manipulation des entrée/sortie et est indispensable pour la gestion de plugin. La deuxième partie constitue un rappel sur les notions de composition et d'héritage. D'une manière générale, il ne faut pas perdre de vue la documentation java :
La classe File (paquetage java.io) ne réfère pas exactement à un fichier. C'est soit le nom d'un fichier particulier soit un ensemble de noms de fichiers dans un répertoire. Dans ce cas, la méthode File[] listFiles() de la classe File renvoie un tableau de Fichiers (type File).
Choses à connaitre :
void mkdirs()
; ...),Pour une information exhaustive et détaillée sur les fichiers, consulter l'API.
L'exercice qui suit est inspiré du livre « Thinking in Java » (http://mindview.net/Books/TIJ4).
Cet exercice est utile si nous visons la fouille d'un répertoire de dépôt de plug-ins.
Travail à faire :
File[] listFiles()
).Pour le troisième point, vous allez créer un filtre (interface FilenameFilter) que nous allons mettre en œuvre de trois façons différentes :
En paramètre, de votre programme, il y aura un argument optionnel : un filtre (par exemple, symboliquement .class). Pour ce filtrage, l'outil le plus puissant est l'utilisation d'expressions régulières.
Depuis Java 7 il existe une alternative à la traversée "manuelle" d'une arborescence qui fait appel au patron de conception visiteur. Le code obtenu est beaucoup plus concis mais ne fonctionne que sur les versions récentes de Java.
Les expressions régulières sont implémentées dans le package java.util.regex, et en particulier dans les classes Pattern et Matcher. Les expressions régulières s'utilisent de la façon suivante :
Pattern p = Pattern.compile(regex);
// regex est une chaîne représentant une expression régulière ;Matcher
pour chaque chaîne : Matcher m = p.matcher("chaine") ;
Matcher
permet de réaliser différentes opérations dont boolean matches()
pour savoir si l'expression régulière s'applique entièrement à la chaîne et lookingAt() pour savoir si la chaîne (depuis son début) correspond à l'expression régulière.Les expressions régulières sont très variées (et assez standards) :
Exemples de filtres :
Pour mettre en œuvre le filtrage, il faut utiliser l'interface FilenameFilter et sa méthode « public boolean accept(File dir, String name) ; » qui doit renvoyer true si le fichier de nom « name » est dans le répertoire « dir ».
Note : il ne s'agit pas ici de maîtriser les expressions régulières, mais plutôt d'en comprendre le fonctionnement. Il vous incombe de regarder plus en détail, par exemple les fonctionnalités de recherche et de remplacement qui ne sont pas évoquées ici.
L'objectif est de vous faire (re-)découvrir les entrées-sorties en Java. En Java, les entrées sorties sont regroupées dans les packages java.io (input-output) et java.nio (new input output). L'objectif de java.nio (JDK 1.4) est d'améliorer l'efficacité des programmes (vitesse) en introduisant notamment les notions de canaux et de tampon (channel et buffer) qui sont assez bas niveau. La plupart des classes de java.io ont été réécrites ou remplacées par de nouvelles classes de java.nio. Nous ne traiterons pas de ces « nouveautés », pour en savoir plus sur java.nio lisez le chapitre 12 de « Thinking in java » ou consultez la documentation java.
Les entrées-sorties reposent donc sur des flux d'octets, InputStream en lecture et OutputStream en écriture et sur des flux de caractères avec les Reader en lecture et les Writer en écriture. Toutes ces classes de java.io sont des classes abstraites. Ces classes proposent des méthodes read() et write() [soit des octets, soit des caractères, soit des int] et java disposent de classes plus évoluées pour lire/écrire des lignes, des double, etc.
Les sources d'entrées sorties sont multiples : des fichiers, des chaînes de caractères, etc. Pour les applications à multi processus et la communication entre deux processus, les <Pipe> (PipeInputStream par exemple) sont fournies dans Java. (nous ne les étudierons pas).
Pour la plupart, ces méthodes peuvent lever des java.io.IOException qu'il vous faudra attraper (avec try/catch)!
On veut écrire un programme Java (une classe SeLit) qui lit un fichier texte et l'affiche sur la console. Pour tester ce programme on essaiera de lire le code source du programme lui-même (le fichier SeLit.java).
Compléter le code ci-dessous:
Pour écrire dans un fichier texte, il faut utiliser conjointement les classes FileWriter et PrintWriter.
Travail à faire :
La classe java.lang.System propose un flot d'entrée standard (System.in) et deux flots de sortie standards (System.out et System.err). System.in est de type InputStream. Par exemple pour lire une chaîne sur l'entrée standard, il suffit d'écrire le code suivant qui utilise la classe Scanner :
Vous manipulez System.out depuis longtemps. Tout comme System.err, il s'agit d'instances de la classe PrintStream.
Chacun de ces flots peut être redirigé vers un autre flot (un fichier par exemple). Bien sûr, il faut préalablement sauvegarder le flot initial, affecter le nouveau (avec les méthodes System.setIn, setOut ou setErr) et finalement restaurer le flot initial.
Travail à faire : modifier la classe SeLit pour rediriger la sortie standard vers un fichier (ex. Output.txt).
Ce sujet de TP a été rédigé par Frédéric Mallet.