Vous n'êtes pas connecté. Connexion
|
|
Frédéric Mallet > Programmation Objet et Patrons de conception - 2011/2012 > TD1 - Entrées/Sorties
TD1 - Entrées/SortiesDe $1Table des matièresIntroductionCe td/tp fait un rappel sur la manipulation d'entrées/sorties indispensable pour la gestion de plugin. La deuxième partie constitue un rappel sur les notions de composition et d'héritage. La troisième partie s'intéresse à un patron de structure appelé Adaptateur. D'une manière générale, il ne faut pas perdre de vue la documentation java :
Pour commencer, nous pouvons nous contenter de faire du java avec un simple éditeur de texte. Vous utiliserez donc un simple éditeur de texte et vous compilerez en ligne avec javac. Vérifiez que vous disposez d'un JDK (tapez javac dans une console). Exercice 1 : la classe FileLa 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 String[] list() de la classeFile renvoie un tableau de chaînes de caractères (type String). Choses à connaitre :
Pour une information exhaustive et détaillée sur les fichiers, consulter l'API de Sun. 1.a) Création d'un programme qui liste le contenu d'un répertoire, avec filtrageL'exercice qui suit est inspiré du livre « Thinking in Java » (http://mindview.net/Books/TIJ4). Cet exercice est utile si nous visons la scrutation d'un répertoire de dépôt de plug-ins. Travail à faire :
Pour le second point, vous allez créer un filtre (interface FilenameFilter) que nous allons mettre en œuvre de trois façons différentes :
Les classes internes sont un outil supplémentaire pour permettre de disposer de la puissance de l’héritage via la composition (ceci est en complément des interfaces). Les classes anonymes permettent de cacher tout en assurant une certaine séparation d’une partie de l'implémentation, cependant, cela peut vite devenir illisible. A utiliser judicieusement. 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. 1.b) Quelques exercices sur les expressions régulièresLes 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 :
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. Exercice 2 : entrées - sortiesL'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.iosont 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. 2.a) Exemple d'utilisation : lecture et écriture d'un fichier texte.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: import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class SeLit { static void lecture(Scanner source) { while(source.hasNextLine()) { String s = source.nextLine(); System.out.println(\"LU:\"+s); } } static public void main(String[] args) { // A compléter } } Pour écrire dans un fichier texte, il faut utiliser conjointement les classes FileWriter et PrintWriter. Travail à faire :
2.b) Entrées et Sorties standards.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 : Scanner sc = new Scanner(System.in); System.out.println(sc.nextLine()); 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). Exercice 3 - Le patron AdaptateurLa paquetage java.io propose plusieurs exemples d'Adaptateurs dont notamment les classes InputStreamReader et OutputStreamWriter qui adaptent des flots d'octets aux flots de caractères. Cet exercice sert à illustrer la mise en oeuvre du patron Adaptateur en recréant un équivalent simplifié de la classe OutputStreamWriter. Il est donc absolument interdit de l'utiliser directement ! 3.a) MyStreamWriterOn suppose qu'on dispose d'un côté d'un objet de type OutputStream et de l'autre d'un programme qui sait (veut) écrire seulement dans des objets de type Writer. On veut faire une classe d'adaptation. Ecrire une classe MyStreamWriter qui offre une solution.
3.b) WriterOutputStreamSauriez-vous faire l'adaptation inverse ? C'est-à-dire adapter un objet de type Writer pour pouvoir l'utiliser avec des classes qui ne savent manipuler que des OutputStream ! Cela peut par exemple servir avec les méthodes System.setOut ou System.setErr pour utiliser un Writer alors qu'un PrintStream est imposé par l'API !
Mots clés:
|
Powered by MindTouch Deki Open Source Edition v.8.08 |