Sérialisation sur le système de fichiers. Gestion des exceptions en Java. Christophe Gravier, Frédérique Laforest, Julien Subercaze Télécom Saint-Étienne Université Jean Monnet {pnom.nom}@univ-st-etienne.fr FI2_INFO4 2012 2013 it tse ujm 1 / 24
Plan Objectifs Sérialisation Gestion des exceptions 2 / 24
Objectifs pédagogiques Obligatoires Sérialisation buffered et unbuffered de types primitifs et d instances de classes en JDK 7 Plus de détails sur http://docs.oracle.com/javase/ tutorial/essential/io/index.html Gestion des exceptions en Java Optionnel Utiliation de la nouvelle API de gestion de fichiers du JDK 7. 3 / 24
Plan Objectifs Sérialisation Gestion des exceptions 4 / 24
Sérialisation. Action de sérialiser Rendre l instance d une classe persistente. Persistente? Il s agit d opérer une transformation réversible de l instance dans une forme (textuel, tableau de bits, etc.). c est donc une opération de sauvegarde d élément en mémoire (RAM) sur un support (disque dur, réseau, etc.) Exemple Un logiciel de traitement de texte sérialise un document sur le système de fichier lors de l opération de sauvegarde, et désérialise le document pour le charger en mémoire lors de l opération de chargement. 5 / 24
Processus de sérialisation/désérialisation Programme en mémoire Flux de 8 bits (byte stream) Database Fichiers Socket Disque dur Réseau Désérialisation (input stream) Sérialisation (output stream) Fig.: Les processus de sérialisation/désérialisation. 6 / 24
Byte streams Principe Un programme Java utilise de flux d octets en Input/Output (I/O) Toutes les classes de I/O héritent des classes InputStream et OutputStream 7 / 24
Exemple 1 public static void main ( String [] args ) 2 { 3 FileInputStream in = 4 new FileInputStream (" doc. txt "); 5 6 FileOutputStream out = 7 new FileOutputStream ("doc - copie. txt "); 8 int c; 9 while ((c = in. read ())!= -1) { 10 out. write (c); 11 } 12 13 in. close (); 14 out. close (); 15 } 8 / 24
Datatype I/O ByteStreams sont des primtives de sérialisation de bas niveau ByteStreams sont des structures de données pour la sérialisation bas niveau pas forcément pratique pour toutes les structures de données plus ou moins complexes, et qu on aimerait ne pas avoir à convertir en byte streams nous même. exemple: les chaînes de caractères (String) Sérialiser des chaînes On utilise non plus un flux de d octets mais un flux de caractères Un flux de caractère réalise des opérations d I/O caractère par caractère (et non plus octet par octet) 9 / 24
Exemple flux I/O de caractères 1 public static void main ( String [] args ) 2 { 3 FileReader in = 4 new FileReader(" doc. txt "); 5 6 FileWriter out = 7 new FileWriter("doc - copie. txt "); 8 int c; 9 while ((c = in. read ())!= -1) { 10 out. write (c); 11 } 12 in. close (); 13 out. close (); 14 } So what? I/O de chaînes UTF-8, donc par train de 16 bits (et non plus 8 comme avec FileInputStream et FileOutputStream) 10 / 24
Exemple flux I/O de lignes de caractères 1 public static void main ( String [] args ) 2 { 3 BufferedReader in = 4 new BufferedReader(" doc. txt "); 5 6 PrintWriter out = 7 new PrintWriter("doc - copie. txt "); 8 9 String l; 10 while (( l = in.readline())!= null ) { 11 out.println(l); 12 } 13 in. close (); 14 out. close (); 15 } 11 / 24
Buffered and unbuffered I/O BufferedReader in = new BufferedReader("doc.txt");??? Une méthode unbuffered écrit/lit octet par octet, caractère par caractère, ligne par ligne, etc. sur le support de sérialisation (système de fichier, réseau, etc.) c est coûteux en terme d accès au support et concurrence des programmes dans l ordonnanceur des processus de l OS! Pour minimiser cela, les méthodes buffered: remplissent une zone mémoire lors d opération d écriture (et effectue la sérialsiation sur le support lorsque la zone mémoire est pleine) vide une zone mémoire lors d opération de lecture (et effectue la désérialisarion à partir du support lorsque la zone est vide) les sérialisations buffered disposent de la méthode flush() pour forcer le vidage de la mémoire avant que celle-ci ne soit pleine ou vide suivant si l on désérialise ou sérialise. 12 / 24
Data streams Et si je dois sérialiser autre chose que des octets ou des caractères? On utilise pour les types primitifs ((boolean, char, byte, short, int, long, float, et double) les Data streams, et pour les instances de classes les Object Streams 13 / 24
Exemple de Data stream buffered sur le filesystem 1 String datafile = " invoicedata "; 2 double [] prices = { 19.99, 9.99, 15.99, 3.99, 4. 99 }; 3 int [] units = { 12, 8, 13, 29, 50 }; 4 String [] descs = { " Java T- shirt ", 5 " Java Mug ", 6 " Duke Juggling Dolls ", 7 " Java Pin ", 8 " Java Key Chain " }; 9 10 DataOutputStream out = new DataOutputStream ( 11 new BufferedOutputStream ( 12 new FileOutputStream ( datafile ))); 13 14 for ( int i = 0; i < prices. length ; i ++) { 15 out. writedouble ( prices [i ]); 16 out. writeint ( units [i ]); 17 out. writeutf ( descs [i ]); 18 } 19 out. close (); 14 / 24
Exemple Object streams 1/2 1 class Personne implements java.io.serializable { 2 private String nom = ""; 3 public Personne ( String n) { this. nom = n; } 4 public String getnom () { return nom ; } 5 } 6 7 public void serialisepersonne ( Personne p) 8 { 9 FileOutputStream fout = 10 new FileOutputStream (p. getnom ()+ ". obj "); 11 12 ObjectOutputStream oos = 13 new ObjectOutputStream ( fout ); 14 15 oos. writeobject ( chris ); 16 oos. close (); 17 } 15 / 24
Exemple Object streams 2/2 1 public Personne deserialisepersonne ( Personne p) 2 { 3 FileInputStream fin = 4 new FileInputStream (p. getnom ()+ ". obj "); 5 6 ObjectIntputStream ois = 7 new ObjectInputStream ( fin ); 8 9 // transtypage necessaire 10 Personne p = ( Personne ) ois. writeobject ( chris ); 11 return p; 12 ois. close (); 13 } 16 / 24
Plan Objectifs Sérialisation Gestion des exceptions 17 / 24
Exception? Et si... Et si le fichier dans lequel nous voulons sérialiser n existe pas? Et si la base de données était saturée? Et si l utilisateur exécutant le programme n a pas les droits sur le fichier en lecture? Et si... Motivations Pour palier à ces problèmes, Java fournit un mécanisme de gestion des exceptions. La gestion des exceptions n est pas un mécanisme uniquement appliqué au I/O dans le language... mais c est une bonne occasion pour vous en parler! 18 / 24
Gestion des exceptions en Java Instance de la classe Exception Lorsqu un problème survient à l exécution d un programme, une instance d une classe héritant de la classe java.lang.exception est créé. Cette instance remonte dans la pile d appel de méthodes jusqu à ce qu elle soit traitée Dans le cas où l exception n avait pas explicitement été prévu par le programmeur (comme une sous-classe de la classe Exception), une instance de la classe Exception est créé. 19 / 24
Exemple d exception Imaginons que je souhaite gérer l exception d une adresse email ne contenant pas d aérobase dans une saisie à l entrée standard. Pour cela, je commence par créer une nouvelle classe dérivant de la classe Exception. 1 public class BadEmailException extends Exception { 2 public BadEmailException ( String msg ){ 3 super ( msg ); 4 } 5 } 20 / 24
Relai de l erreur potentielle dans la pile d appel 1 public class EnterInfo { 2 public saisieemail () throws BadEmailException { 3 String mail ; 4 System. out. println (" Donner l email "); 5 System.in. read ( mail ) 6 if (! mail. contains ("@")) 7 { 8 throw new BadEmailException (" le " + 9 " mail "+ mail +" ne contient pas "+ 10 "le caractere @ "); 11 } 12 } 13 } 21 / 24
Gestion de l exception : Try-Catch-Finally 1 public class Test { 2 public test () { 3 try { 4 // appel " risqué" 5 String mail = new EnterInfo (). saisieemail (); 6 } 7 catch ( BadEmailException reason ) { 8 // exception detectée 9 System. out. println (" Erreur : "+ 10 reason. getmessage ()); 11 } 12 finally { 13 // dans tous les cas on passe ici 14 System. out. println (" Fin de l appel "+ 15 " de la methode."); 16 } 17 } 22 / 24
Exemple: Et si le fichier n existe pas? 1 FileInputStream fis = null ; 2 BufferedInputStream bis = null ; 3 try { 4 fis = new FileInputStream ( file ); 5 bis = new BufferedInputStream ( fis ); 6 } 7 catch ( Fi lenot Found Except ion e) { 8 System. out. println ("Le fichier "+ 9 file. getname ()+ "n exsite pas "); 10 } 11 return bis ; 23 / 24
The End 24 / 24