====== TP CCI Java - Première partie ====== Avant de commencer, quelques liens utiles: * [[http://java.sun.com/javase/6/docs/api/|Manuel de référence des classes Java fournies avec le JDK]]. Il est **fortement** conseillé de regarder rapidement la documentation des classes que vous manipulez. En particulier, regardez les constructeurs permettant de créer des objets de la classe en question. Il est également conseillé de regarder les méthodes indiquées dans l'énoncé du TP. ===== Affichage des arguments en ligne de commande ===== **Objectif:** créer une première application Java. Lancer NetBeans. Créer un nouveau projet: * de type: General (ou Java) -> Java Application * avec comme nom: ''Fichiers'' * décocher l'option "//Create Main Class//" Dans "//Source packages//", ajouter un nouveau package appelé ''utilfichiers''. //Toutes les classes de ce TP sont à créer dans ce package.// Créer une classe appelée ''Arguments''. Supprimer le constructeur de la classe, s'il a été créé par Netbeans. Ajouter à la classe une méthode ''main'' ayant pour signature: public static void main(String [] args) Dans cette méthode, ajouter le code nécessaire pour afficher le contenu du tableau ''args'', à raison d'une case par ligne. Cliquer ensuite avec le bouton droit sur le projet et sélectionner "//properties//". Sélectionner "//Run//". Cliquer sur le bouton "//Browse//" pour "//Main class//" et choisir ''utilfichiers.Arguments''. Dans le champ "//Arguments//", insérer quelques mots séparés par des espaces. Cliquer sur "//OK//". Lancer l'exécution du programme grâce au premier bouton avec un triangle vert (Run Main Project (F6)). Compiler votre projet (icône bleue avec une clé anglaise ou un marteau (Build Main Project (F11))), puis lancer un interpréteur de commandes et se placer dans le répertoire du projet NetBeans. Exécuter la commande: java -cp dist/Fichiers.jar utilfichiers.Arguments toto titi tutu :!: Si une erreur intervient concernant une version des classes Java, utiliser la version 1.6 de java fournie sur la machine :!: Qu'en déduire sur le tableau ''args''? ===== Lecture d'un fichier ===== L'objectif est de créer une application pour lire le contenu d'un fichier. ==== Classe pour lire un fichier ==== Tout d'abord, on créée une classe qui va permettre de lire des lignes dans un fichier. Créer une nouvelle classe ''LecteurDeFichier'', toujours dans le package ''utilfichiers''. Ajouter à la classe un champ de type ''BufferedReader''. Ajouter également le code pour importer toutes les classes du package ''java.io''. Créer un constructeur avec((ou ajouter au constructeur s'il existe déjà)) un argument de type ''String'', et qui correspondra au nom du fichier à lire. Utiliser cet argument pour construire un objet de type ''FileReader'', lui-même utilisé pour initialiser le champ précédemment créé. N'hésitez à lire un peu la documentation de ces classes si vous ne voyez pas comment faire. NetBeans signale alors une erreur: déplacer la souris au-dessus de la partie soulignée en rouge afin de voir l'erreur, ou bien cliquer sur le bouton bleu (Build Main Project (F11)) à gauche du bouton (Run). On nous signale que l'exception ''java.io.IOException'' n'est pas gérée. On l'ajoutera ici dans une déclaration ''throws'' entre la signature du constructeur et son code: public LecteurDeFichier (String nomFichier) throws java.io.IOException { ... } Pour finir, créer une méthode lireLigne ayant la signature suivante: public String lireLigne() et qui renvoie une ligne lue dans le fichier. On pourra utiliser la méthode ''readLine()'' du BufferedReader. Comme pour le constructeur, on ajoutera la déclaration ''throws java.io.IOException''. ==== Test de la classe ==== On créée à présent une classe qui va utiliser la précédente pour afficher le contenu d'un fichier. Créer une nouvelle classe ''TestLecteurFichier''. Supprimer le constructeur et ajouter une méthode ''main'' avec la même signature que précédement. Dans le corps de la méthode, créer et initialiser une variable de type ''LecteurDeFichier''. On utilisera le premier argument de la ligne de commande comme nom de fichier. Comme la méthode ''readLine()'' de la classe ''BufferedReader'' renvoie ''null'' en cas de fin de fichier, la méthode ''lireLigne()'' se comportera de la même manière. Créer une variable de type ''String'' et, à l'aide de cette variable et d'une boucle ''do { ... } while (...);'' utiliser la méthode ''lireLigne()'' du ''LecteurDeFichier'' pour afficher le contenu du fichier. Enfin, ajouter une déclaration ''throws java.io.IOException'' comme pour la méthode et le constructeur précédents. Ici, on aurait également pu entourer ce code à l'aide d'un ''try { ... } catch ( ... ) { ... }'' afin de rattraper l'''IOException'' et d'afficher un message d'erreur((A faire après le cours sur les exceptions)). Dans les propriétés du projet, changer la classe principale (//Main class//) pour sélectionner ''utilfichiers.TestLecteurFichier''. Changer également les arguments pour indiquer * sous Windows: ''src\utilfichiers\LecteurDeFichier.java'' * sous Linux ou MacOS: ''src/utilfichiers/LecteurDeFichier.java'' Exécuter le projet et vérifier que le code source de la classe ''LecteurDeFichier'' est bien affiché. Essayer avec d'autres fichiers en changeant l'argument en ligne de commande dans les propriétés du projet. On peut aussi essayer dans l'interpréteur de commandes. ===== Analyseur ===== L'objectif est de réaliser un mini programme java capable de trouver des occurrences de mot dans un fichier ou dans un texte tapé au clavier (un peu à la manière du programme fgrep sous Unix). ==== Une interface pour la lecture ==== L'objectif ici est de créer une interface Java pour nous abstraire de la manière dont on récupère les lignes (en pratique on les obtiendra soit à partir d'un fichier en utilisant la classe précédente, soit à partir du clavier). Créer une //interface// appelée ''Lecteur''. Lui ajouter une méthode publique ''lireLigne'' qui ne prend pas d'argument et renvoie une chaîne de caractères (''String''). Déclarer ensuite que la classe LecteurDeFichier implémente cette interface grâce à la déclaration ''implements Lecteur'' que l'on placera entre le nom de la classe et sa première accolade ouvrante. Compiler le projet (F11). L'erreur indique que le "contrat" spécifié par l'interface ''Lecteur'' n'est pas respecté par ''LecteurDeFichier'' car sa méthode ''lireLigne()'' peut laisser échapper une ''IOException''. Corriger le problème en ajoutant la déclaration ''throws IOException'' à la méthode ''lireLigne()'' dans **l'interface ''Lecteur''**. ==== Une deuxième implantation de l'interface ==== On se retrouve maintenant avec une première implémentation de l'interface Lecteur qui lit dans un fichier. L'objectif est à présent de faire une deuxième implémentation qui elle va lire les lignes au clavier. Créer une nouvelle classe ''LecteurClavier''. Cette classe sera similaire à la classe ''LecteurDeFichier'': * Toutes deux implémentent l'interface ''Lecteur'' * Toutes deux ont un champ qui est un ''BufferedReader'' qui sert à l'implantation de la méthode ''lireLigne()''. avec quelques différences: * Le ''BufferedReader'' de la classe ''LecteurDeFichier'' est initialisé à partir d'un ''FileReader'', lui même créé à partir d'un nom de fichier passé en argument. Celui de la classe ''LecteurClavier'' sera créé à partir d'un ''InputStreamReader'', lui-même créé à partir du champ statique ''System.in''. * Le constructeur de la classe ''LecteurClavier'' ne prend pas d'arguments. ==== Une classe pour l'analyse ==== On passe maintenant à la création d'une classe qui va analyser les lignes lues par les classes que l'on vient d'écrire. Créer une classe ''Analyseur''. Ajouter à la classe un champ ''mot'' de type ''String''. Modifier le constructeur de façon à ce qu'il prenne un paramètre pour initialiser ce champ. Créer une méthode ''analyse()'' ayant la signature suivante: public void analyse(Lecteur lecteur) throws IOException La méthode devra lire les lignes grâce au lecteur jusqu'à la fin (i.e. jusqu'à ce que la méthode ''lireLigne()'' renvoie ''null''). Si la ligne contient mot, afficher le numéro de la ligne puis ":" puis la ligne elle-même. La méthode ''contains'' dans la classe ''String'' peut s'avérer utile ici. On termine en créant une méthode main pour servir de point d'entrée au programme et qui va mettre en place et utiliser les bonnes classes et les bonnes méthodes pour réaliser l'analyse: Ajouter à la classe ''Analyseur'' une méthode **statique** ''main''. Dans cette méthode, on définit une variable de type ''Lecteur''. Si il y a au moins deux arguments sur la ligne de commande, le lecteur est défini comme un ''LecteurDeFichier'', le nom du fichier étant donné par le deuxième argument de la ligne de commande. Sinon le lecteur est défini comme un ''LecteurClavier''. Utiliser ensuite le premier argument de la ligne de commande pour créer un ''Analyseur''. Enfin appeler la méthode ''analyse()'' de l'analyseur avec comme argument le lecteur défini précédement. On fera attention de gérer les ''IOException'' avec un throws ''java.io.IOException'' ou avec ''try/catch'' approprié((après le cours sur les exceptions)). Changer les propriétés du projet pour choisir ''utilfichiers.Analyseur'' comme classe principale et changer les arguments en ligne de commande pour tester votre programme.