TP de Java Exceptions et E/S Sujets abordés dans ce TP : Bloc try/catch/finally Déclenchement d exception Redéfinition d exception Taxonomie des exceptions Gestion de fichiers Tokenizer 1) Les erreurs et les exceptions Introduction catch (IOException ioe) { System.out.println(" E/S problem :" + ioe); catch (NumberFormatException nfe) { System.out.println(" NumberFormat problem " + nfe); finally { System.out.println("#4"); Durant l exécution d un programme, il peut se produire des événements anormaux (et inattendus) comme par exemple : un utilisateur pourrait écrire un nom de fichier inadmissible, un dossier pourrait contenir des données corrompues, etc. On peut prendre en compte des circonstances de ce type en Java via les mécanismes d exception. Un sous-arbre de la hiérarchie de classes, ayant pour classe racine la classe java.lang.throwable, y est consacré. Aider vous de la documentation de ce package dans l API specification afin d analyser les différents exemples durant ce TP. En Java, la gestion des exceptions se fait via l emploi d une structure de type try/catch/finally. L exemple suivant donne une première implémentation d exception pour la lecture d un fichier texte, et le résultat commenté de l exécution de cet exemple. import java.io.fileinputstream; public class Tp3_ex1 { String filename = "todo.txt"; String nstring = "10"; FileInputStream fis; System.out.println("#1"); fis = new FileInputStream(fileName); System.out.println("#2"); Si todo.txt existe et nstring est un nombre entier alors la sortie de ce programme est : #1 #2 #3 #4 Si le fichier de nom contenu dans la String filename n existe pas alors la sortie de ce programme est : #1 E/S problem :java.io.filenotfoundexception: todo.txt (Le fichier spécifié est introuvable) #4 Si la chaîne de caractères nstring n est pas un nombre entier alors : #1 #2 NumberFormat problem java.lang.numberformatexception: For input string: "10sd" #4 Conclusions: - une exception produite dans le bloc «try» est manipulée par la clause «catch» assortie - quand une exception est produite tout le code dans le bloc d'essai après l'endroit où l'exception a eu lieu n'est pas exécuté. - «finally» est toujours exécuté Integer n = new Integer(nString); System.out.println("#3"); 1
Première mise en œuvre La forme la plus générale de l implémentation du bloc try/catch/finally est: // instructions : // certaines sont sûres, certaines pourraient déclencher //des exceptions catch (SpecificException e) { // faites quelque chose pour SpecificException, //peut-être un essai pour récupérer les données // qui pourraient être perdues catch (OtherException e) // faites quelque chose pour OtherException catch (GeneralException e) { // faites quelque chose pour GeneralException finally { // code qui doit être exécuté que l exception ait été // déclenchée ou non Remarque : «finally» est facultatif. Implémenter et mettre en oeuvre le code suivant, commenter. int a; try {a=1; a= 1/0; catch(exception e) {System.out.println("Number Exception"); finally {a=-1; System.out.println(a); Déclencher des exceptions Nous continuerons dans cette partie du TP en examinant comment des exceptions peuvent être déclenchées. En effet, dans une application c est l analyse des données véhiculées qui peut conduire cette application à déclencher une ou des exception(s). Dans ce cas, le programmeur Java aura recours à l instruction throw : throw new Exception(); Il existe deux moyens d utiliser l instruction trow : 1. dans un bloc try, 2. dans une méthode déclarée comme susceptible de déclencher une/des exception(s) à l aide du mot clé throws. Implémenter et mettre en œuvre le code suivant, commenter : import java.io.*; class Test1 { void test1() { throw new Exception(); catch(exception e) {System.out.println("first exception a"); void test2() throws Exception{ throw new Exception(); public class Except { public static void main(string args[]) { new Test1().test1(); new Test1().test1(); catch(exception e) {System.out.println("first exception b"); Dans l exemple précédent, vous avez vu qu une méthode susceptible de déclencher des exceptions se doit de les déclarer à l aide du mot clé throws. Il possible pour une méthode de déclarer plusieurs types d exceptions de la manière suivante : public int monmethode()throws IOException, MonException1,MonException2 { 2
throw new IOException( quelque-chose ); Définir des exceptions L API specification permet d utiliser un ensemble d exceptions standards. Il est cependant possible pour le programmeur Java de définir ses propres exceptions. Pour cela, il doit définir une classe héritant de classe Exception. Implémenter et mettre en oeuvre l exemple suivant, commenter : Taxonomie des exceptions Les exceptions en Java sont définies selon une certaine taxonomie. La figure suivante présente cette taxonomie, vous pouvez consulter le package java.lang dans l API specification pour plus de détails. import java.io.*; class CompteException extends Exception{ String motif; CompteException(String s) { super(s); motif=s; public class Tp3_ex2 { private int compte; Tp3_ex2(int montant) { this.compte = montant; void retireargeant(int montant) throws CompteException { if (montant > compte) { throw new CompteException("Possibilités de retrait épuise"); else {compte = compte - montant; Tp3_ex2 compte1 = new Tp3_ex2(1000); compte1.retireargeant(2000); catch (CompteException ce) {ce.printstacktrace(); 1. Les exceptions «vérifiées» (checked) traitent des problèmes qui peuvent surgir dans un programme considéré comme «valide». Typiquement, ce type d exception concerne : les problèmes d installation de package, les erreurs utilisateurs, les problèmes de lecture/écriture, etc. Un certains nombre de classes standards existent comme les classes : IOException, ClassNotFoundException, etc. 2. Les exceptions d'exécutions (runtime) traitent typiquement les bogues apparaissant durant l exécution des programmes. Un problème type est celui de l accès à des données non allouées au sein d un tableau (ou dépassement d indice). Dans un programme correctement implémenté, ce type d exception devrait en théorie ne jamais se produire. Un certain nombre de classes standards existent comme les classes : NumberFormatException, NullPointerException, ArrayIndexOutOfBoundsException, etc. 3. Les exceptions d erreurs (error) traitent les problèmes atypiques qui ne peuvent être associés aux deux premières catégories d exceptions. Ces problèmes peuvent concerner des bogues d exécution, mais traitent le plus souvent des problèmes systèmes comme le dépassement de mémoire. Un certains nombre de classes standards existent comme les classes : OutOfMemoryError, StackOverflowError, etc. 3
L exemple suivant met en œuvre ces différentes exceptions, implémenter le : import java.io.fileinputstream; public class Tp3_ex3 { public static void main(string args[]) { int x = 1;//-1 int y = 1;//0 int z[]= new int[3]; // Runtime Exceptions System.out.println(" x/y="+(x/y)); System.out.println(" z[x]="+z[x]); // Checked Exception try{ FileInputStream f = new FileInputStream("todo.txt"); catch(ioexception ioe) { ioe.printstacktrace(); // Error int M = 1000000000; Double[] d = new Double[M]; Le mettre en oeuvre de la façon suivante, commenter : Si y == 0 alors la sortie contient : java.lang.arithmeticexception: / by zero C'est une Runtime Exception. 2) Classes d entrée et de sortie Introduction Dans cette partie nous présentons quelques classes standards Java pour l accès de données en entrée/sortie de vos programmes. Ces classes traitent donc de problèmes susceptibles de déclencher des exceptions, elles s appuient sur les notions présentées en première partie de ce TP. Classe java.io.file La classe java.io.file représente le nom d'un dossier ou d'un fichier qui pourrait exister sur le système de fichiers de l'ordinateur. Ses méthodes principales pour la navigation sont : boolean exists() boolean isdirectory() boolean isfile() String[] list() Quelques méthodes de non-navigation sont : boolean delete() boolean mkdir() Implémenter et mettre en oeuvre l exemple suivant, commenter : import java.io.file; public class Tp3_ex4 { String name = "todo.txt"; File f = new File(name); System.out.println("f.exists()" + f.exists()); System.out.println("f.isDirectory()" + f.isdirectory()); Si y!=0 && x== -1 par example la sortie contient: java.lang.arrayindexoutofboundsexception: -1 C est une Runtime Exception. Si (y!=0)&&(x>=0)&&(x<3) mais n existe pas un fichier avec le nomme todo.txt alors : java.io.filenotfoundexception: todo.txt (Le fichier spécifié est introuvable) C est une Checked Exception. Si y et x sont ok et todo.txt existe alors la sortie contient : java.lang.outofmemoryerror C est une Error. if (f.isdirectory()) { String[] list = f.list(); for (int i = 0; i < list.length; i++) { System.out.println(" " + list[i]); 4
Classe java.io.randomaccessfile La classe java.io.randomaccessfile permet de chercher dans une position désirée dans un fichier, et alors lire ou écrire une quantité désirée de données. Implémenter et mettre en oeuvre l exemple suivant, commenter : import java.io.file; import java.io.randomaccessfile; public class Tp3_ex5 { File f = new File("nomFichier"); RandomAccessFile raf = new RandomAccessFile(f, "rw"); char ch = raf.readchar(); raf.seek(f.length()); raf.writechars("astring"); raf.close(); catch (IOException e) { e.printstacktrace(); Classe java.io.bufferedreader Implémenter et mettre en oeuvre l exemple suivant pour la lecture de données au clavier, commenter : import java.io.bufferedreader; import java.io.inputstreamreader; public class Tp3_ex6 { BufferedReader in = new BufferedReader( new InputStreamReader(System.in)); String str = ""; while (str!= null) { System.out.print("> prompt "); str = in.readline(); System.out.println(str); catch (IOException e) {e.printstacktrace(); Implémenter et mettre en oeuvre l exemple suivant pour la lecture d un fichier texte, commenter : import java.io.bufferedreader; import java.io.filereader; public class Tp3_ex7 { BufferedReader in = new BufferedReader( new FileReader("todo.txt")); String str; While ((str = in.readline())!= null) {System.out.println(""+str); in.close(); catch (IOException e) {e.printstacktrace(); Classe java.util.stringtokenizer La «tokenization» permet de décomposer une chaîne de caractères donnée selon des tokens donnés. Considérons que nous lisons une ligne de ce type : bx 20 ax 10 5
La décomposition en tokens de cette chaîne a pour but de trouver «bx» et «ax» et les numéros 10 et 20. Implémenter et mettre en oeuvre l exemple suivant, commenter : import java.util.stringtokenizer; public class Tp3_ex8 { String astring = "mot1 mot2 mot3"; StringTokenizer parser = new StringTokenizer(aString); while (parser.hasmoretokens()) { System.out.println(parser.nextToken()); Classe java.io.bufferedwriter Implémenter et mettre en oeuvre l exemple suivant, commenter : import java.io.bufferedwriter; import java.io.filewriter; public class Tp3_ex9 { BufferedWriter out = new BufferedWriter(new FileWriter("outfilename")); out.write("astring"); out.close(); catch (IOException e) {e.printstacktrace(); 6