Sie sind auf Seite 1von 24

Entres/Sorties

18/12/07 09:11

Accueil >Programmation >Java >Tutoriel >Principal

Introduction
Un programme peut interagir avec le monde extrieur via son entre standard et ses sorties standards expliques dans le chapitre 4, mais il s'agit l de donnes qui sont temporaires, c'est--dire qu'elles disparaissent lorsque le programme est ferm. Pour pouvoir stocker des donnes de manire permanente, on doit utiliser des fichiers qui sont stocks sur le disque dur et sont donc permanent. On peut lire le contenu de ces fichiers et on peut galement y crire des donnes, il s'agit d'une autre manire pour un programme de communiquer avec le monde extrieur. Les fichiers sont organiss d'une certaine manire, en effet, ils se trouvent sur un disque et dans un certain dossier ou rpertoire. Vous pouvez facilement voir les fichiers que vous possdez en utilisant une invite de commande ou alors l'explorateur en mode graphique disponible sur votre systme d'exploitation, par exemple explorer sous Windows et konqueror (KDE) ou nautilus (Gnome) sous Linux. Ce chapitre s'intresse la manipulation des fichiers et des rpertoires dans un premier temps et ensuite, la deuxime partie du chapitre aborde la lecture et l'criture des fichiers texte. Enfin, pour terminer, la fin du chapitre montre comment procder pour directement stocker des objets dans un fichier pour pouvoir les rcuprer facilement par la suite. Chapitre 11 Suivant

Copyright 2000-2007 UKO. Toute reproduction strictement interdite sans autorisation du webmaster

Site optimis pour Firefox avec une rsolution 1024x768. Page charge en 0.0424800 secondes

http://www.ukonline.be/programmation/java/tutoriel/chapitre12/index.php

Page 1 sur 1

Entres/Sorties : Manipulation des fichiers et rpertoires

18/12/07 09:11

Accueil >Programmation >Java >Tutoriel >Principal >Chapitre 12 : Fichiers

Manipulation des fichiers et rpertoires


La notion de fichier et leur organisation dpendent du systme d'exploitation, en effet, sous Linux, on a par exemple une racine / et puis des rpertoires dans lesquels on retrouve d'autre rpertoires et des fichiers. Sous Windows, on a en plus la notion de lecteur, et on a donc plusieurs racines et on parle de dossier plutt que de rpertoire. Une autre diffrence qui apparait est la manire de spcifier le chemin d'un fichier dans l'arborescence du systme, sous Windows, on spare les dossiers par un \, sous Unix par un / et sous MacOS on retrouve des :. En Java, tout est abstrait un haut niveau et toutes ces notions sont reprises dans une seule classe Java, la classe File qui se trouve dans le package java.io.

Racines de l'arborescence
Comme dit prcdemment, sous Linux, il n'y a qu'une racine, savoir /, mais sous Windows, les fichiers sont organiss dans des lecteurs physique ou logiques. Pour connaitre ces diffrentes racines, on utilise la mthode statique listRoots de la classe File. Cette mthode renvoie un tableau des racines du systme et pour Linux, le tableau ne contiendra qu'un seul lment bien entendu. Le listing suivant montre comment afficher toutes les racines :
1 File[] roots = File.listRoots(); 2 for (File file : roots) 3{ 4 5} System.out.println (file);

listing j12.1 Afficher les racines d'un systme Sous Windows, on pourrait par exemple avoir la sortie suivante : C:\ D:\ E:\ H:\ I:\

Fichier ou rpertoire
La classe File permet de reprsenter les fichiers et les rpertoires, mais comment savoir si un objet File reprsente un fichier ou un rpertoire ? On utilise simplement des mthodes de cette classe, deux mthodes boolenne sont intressantes pour ce faire : isFile et isDirectory qui permettent donc de savoir si on a affaire un fichier ou un rpertoire.
1 File[] roots = File.listRoots(); 2 for (File file : roots) 3{ 4 5} System.out.println (file + " " + file.isDirectory());

listing j12.2 Fichier ou rpertoire Sous Windows, on pourrait par exemple avoir la sortie suivante : C:\ D:\ E:\ H:\ I:\ true false true true true

Chacun des lecteurs physiques ou logiques du systme est donc bien un rpertoire, sauf le lecteur D:\ qui correspond vraisemblablement un lecteur de CD ou DVD ne contenant pas de disque l'intrieur.

Existence et cration

http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page1.php

Page 1 sur 4

Entres/Sorties : Manipulation des fichiers et rpertoires

18/12/07 09:11

Un objet de type File reprsente en fait un chemin abstrait vers un fichier ou un rpertoire, il se peut tout fait que le fichier ou rpertoire reprsent n'existe pas sur le systme, pour savoir si le fichier ou rpertoire reprsent existe ou pas, il faut utiliser la mthode exists. Si le fichier n'existe pas, on peut le crer en utilisant la mthode createNewFile. L'exemple suivant cre un nouvel objet File et cre le fichier sur le systme si celui-ci n'existe pas encore.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 } } } catch (IOException exception) { System.out.println ("Erreur " + exception.getMessage()); } } else { System.out.println ("Cration du fichier echoue"); } else { try { if (file.createNewFile()) { System.out.println ("Cration du fichier russie"); File file = new File ("monfichier"); if (file.exists()) { System.out.println ("Le fichier existe dj");

listing j12.3 Cration d'un fichier On commence donc par crer un objet de type File qui reprsente un fichier qui s'appelle monfichier. Ce fichier est simplement un fichier qui se trouve dans le mme rpertoire que le programme Java. Le programme vrifie ensuite si le fichier existe dj ou pas avec la mthode exists qui renvoie un boolen. Si le fichier n'existe pas encore, on va tenter de le crer avec la mthode createNewFile qui renvoie un boolen si la cration a russi. De plus, cette mthode est susceptible de lancer une exception de type IOException qui reprsente une erreur d'criture sur le disque, ou une limitation des droits d'criture, ... et il faut donc grer l'erreur avec un bloc try-catch tant donn qu'il s'agit d'une exception sous contrle. La classe IOException se trouve galement dans le package java.io. Si vous n'avez pas encore de fichier monfichier dans le rpertoire contenant votre programme Java, la premire excution du programme, le fichier sera donc cr. Et ensuite, la seconde excution, le programme dira que le fichier existe dj. > java TestFileCreation Cration du fichier russie > java TestFileCreation Le fichier existe dj Pour crer un rpertoire, on a une autre mthode qui est mkdir qui permet de crer le rpertoire si celui-ci n'existe pas encore.

Parcours d'arborescence
On va maintenant s'intresser un autre problme, celui qui consiste parcourir toute une arborescence. Il s'agit donc de partir d'un rpertoire et d'ensuite afficher tous les fichiers et rpertoires contenu dans celui-ci, et ce de manire rcursive. Bien entendu la classe File propose des mthodes qui vont nous aider atteindre ce but : on a dj vu la mthode isDirectory qui permet de vrifier si on a affaire un rpertoire ou pas et on va en plus utiliser la mthode listFiles qui renvoie un tableau d'objets de type File reprsentant le contenu du rpertoire.
1 2 3 4 5 private static void printContent (File file, int level) { for (File f : file.listFiles()) { for (int i = 0; i < level; i++) System.out.print ("|\t");

http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page1.php

Page 2 sur 4

Entres/Sorties : Manipulation des fichiers et rpertoires

18/12/07 09:11

6 7 8 9 10 11 12 13 14 15 16 17 } } } } else { System.out.println ("| " + f.getName()); if (f.isDirectory()) { System.out.println ("+ " + f.getName()); printContent (f, level + 1);

listing j12.4 Mthode pour parcourir une arborescence La mthode est assez simple, elle commence par boucler sur tous les fichiers et rpertoires du fichier reu en paramtre grce une boucle for amliore sur file.listFiles(). Ensuite, si on a affaire un rpertoire, il faut faire un appel rcursif. Le reste du code est juste l pour la mise en forme du rsultat sur la sortie standard. Le listing suivant donne un exemple d'utilisation de cette mthode avec un rsultat que l'on obtient sur la sortie standard.
1 public static void main (String[] args) 2{ 3 4 5 6} File file = new File ("I:\\UKO"); System.out.println ("+ " + file.getName()); printContent (file, 1);

listing j12.5 Exemple de parcours d'un rpertoire + UKO | | | | | | | | | | | | | | | | | | | | | | | + Java | + | | | | | + | | | | | | | | | + | | | | | | | | + LaTeX | + | | | | | | | | | | | | | UKO.lnk

Intro | HelloWorld.class | HelloWorld.java IntroEclipse | .classpath | .project | HelloWorld.class | HelloWorld.java Projet1 | .classpath | .project | Projet1.class | Projet1.java HelloWorld | HelloWorld.aux | HelloWorld.dvi | HelloWorld.log | HelloWorld.tcp | HelloWorld.tex | HelloWorld.tps

Faites attention avec cette mthode sous Linux, en effet, si vous avez des rfrences circulaires, la mthode propose ici va boucler infiniment. De plus, la mthode listFiles renvoie null si elle est appele sur un objet File ne reprsentant pas un rpertoire, il faut donc s'assurer que le premier appel est bien fait avec un rpertoire.

Sparateur
Comme vous l'avez peut-tre vu dans le code du listing 12.5, on cre un objet de type File en donnant directement le chemin absolu en paramtre au constructeur. Si l'on souhaite crire une application portable, il est prfrable d'utiliser des chemins relatifs, mais il subsiste un problme, celui du caractre de sparation. En effet, sous Windows, c'est le backslash \ qui spare les rpertoires et sous Unix, on a le slash /. La classe File possde quelques constantes qui reprsente ces donnes qui changent selon le systme d'exploitation. On a la constante separator qui reprsente le caractre utilis pour sparer les rpertoires dans un chemin et on a galement la constante pathSeparator qui reprsente le caractre utilis pour sparer plusieurs chemins pour les variables d'environnement par exemple.
http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page1.php Page 3 sur 4

Entres/Sorties : Manipulation des fichiers et rpertoires

18/12/07 09:11

1 System.out.println ("Le sparateur des rpertoires dans un chemin est " + File.separator); 2 System.out.println ("Le sparateur des chemins est " + File.pathSeparator);

listing j12.6 Sparateurs Le sparateur des rpertoires dans un chemin est \ Le sparateur des chemins est ; Sous Unix, on aura bien sur / comme sparateur des rpertoires d'un chemin et : comme sparateur des chemins. Afin d'tre portable, il est donc bien entendu prfrable de construire les chemins de manire relative et en utilisant ces constantes au lieu de hardcoder les chemins.
1 File file = new File ("data" + File.separator + "movies" + File.separator + "vid.mpg");

listing j12.7 Fichier relatif

Fichiers temporaires
Terminons ce petit tour de la classe File en dcouvrant ensemble comment crer un fichier temporaire, c'est-dire un fichier qui est automatiquement supprim du disque une fois que la machine virtuelle Java quitte correctement. Pour crer un fichier temporaire, il suffit d'utiliser la mthode statique createTempFile qui cre un fichier dans le rpertoire temporaire du systme d'exploitation. Ensuite, on appelle la mthode deleteOnExit pour indiquer que le fichier doit tre supprim lorsque la JVM quitte correctement.
1 try 2{ 3 4 5} 6 catch (IOException exception){} File tmp = File.createTempFile ("nomfichier", ".tmp"); tmp.deleteOnExit();

listing j12.8 Cration d'un fichier temporaire La mthode createTempFile prend deux paramtres : le prfixe et le suffixe du nom qui sera utilis pour le fichier. Il faut de plus attraper l'exception IOException qui est susceptible d'tre lance par la mthode si le fichier ne sait pas tre cr. Prcdent Suivant

Copyright 2000-2007 UKO. Toute reproduction strictement interdite sans autorisation du webmaster

Site optimis pour Firefox avec une rsolution 1024x768. Page charge en 0.0491080 secondes

http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page1.php

Page 4 sur 4

Entres/Sorties : Types de fichier

18/12/07 09:11

Accueil >Programmation >Java >Tutoriel >Principal >Chapitre 12 : Fichiers

Types de fichier
Mais que sont les fichiers ? Les fichiers sont simplement une suite finie de 0 et de 1, en effet, dans le monde de l'ordinateur, tout est fait de 0 et de 1. Nanmoins, on peut distinguer deux sortes de fichiers : les fichiers textes et les fichiers binaires .

Fichiers binaires
Commenons par cette premire classe de fichiers, ce sont les plus faciles dcrire. En fait, tous les fichiers sont des fichiers binaires, c'est--dire qu'ils sont constitus d'une suite finie de 0 et de 1. Ces 0 et 1 sont regroups en blocs de 8 qui sont appels les octets (ou byte en anglais).

fig j12.1 Un fichier binaire On va pouvoir lire et crire de tels fichiers en manipulant ces octets. La taille d'un fichier est par ailleurs donne en octets et il est possible de l'obtenir en utilisant la mthode length des objets File.
1 File logo = new File ("logo.gif"); 2 System.out.println ("L'image fait " + logo.length() + " octets");

listing j12.9 Taille d'un fichier Ces fichiers ne sont donc pas directement lisibles par un tre humain mais sont interprts par les programmes qui les manipulent exploiter l'information qu'ils contiennent et l'utiliser. Un exemple de fichiers binaires sont les images, les fichiers images doivent tre interprts par un programme appropri pour en tirer l'information et pouvoir afficher l'image l'cran par exemple.

Fichiers texte
Les fichiers textes sont galement des fichiers binaires mais dans leur cas, les octets du fichier ont une signification bien particulire et ces fichiers peuvent tre directement lisibles par les humains grce un diteur de texte (Bloc-notes sous Windows, Gedit, Kate sous Linux). On a dj rapidement abord cette reprsentation au chapitre 1. un fichier texte est associ un encodage, c'est--dire une table qui fait la correspondance entre un ou plusieurs octets et un caractre. Un encodage assez courant est l'ASCII-tendu o chaque caractre est reprsent par un octet, le tableau suivant donne quelques-unes des correspondances de cet encodage. Octet Base 10 Caractre 0 9 A Z a z
Page 1 sur 3

0011 0000 48 0011 1001 57 0100 0001 65 0101 1010 90 0110 0001 97 0111 1010 122 1000 0010 130 1000 1010 138

http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page2.php

Entres/Sorties : Types de fichier

18/12/07 09:11

tab j12.1 Quelques correspondances de l'encodage ASCII-tendu Il est donc possible d'ouvrir un tel fichier avec un diteur de texte et de directement voir sa signification. La figure suivante montre un exemple de fichier texte qui contient la phrase tte en l'air encode en ASCIItendu

fig j12.2 Un fichier texte Il existe normment d'encodages diffrents donc par exemple Unicode pour lequel chaque caractre est cod sur 16 bits (2 octets) et permet de reprsenter beaucoup plus de caractres dont les caractres chinois, arabe, japonais, thalandais, ... On reparlera des encodages dans la section suivante qui traite de la lecture de fichier texte.

Hirarchie de classe
On peut faire deux choses avec les fichiers, on peut lire leur contenu et on peut galement y crire du contenu. La lecture et criture de fichiers va bien entendu diffrer selon que l'on traite avec des fichiers binaires ou des fichiers texte. Dans le cadre des fichiers binaires, on va parler de flux d'octets , en effet, la lecture ou l'criture de tels fichiers se passera au niveau des octets tandis qu'avec les fichiers textes, on parle de flux de caractres. Toute une srie de classes sont prvues pour manipuler les fichiers et effectuer des oprations d'entre-sortie. Elles se retrouvent dans le package java.io et quelques-unes sont reprises sur le diagramme de classe de la figure suivante.

fig j12.3 Hirarchie des classes I/O On peut voir que la hirarchie de classes est divise en plusieurs parties, en effet, on retrouve toutes les classes qui ont trait aux entres-sorties et donc pas seulement les fichiers. On a dj rencontr les entres et sorties standard au chapitre 4, rappelez-vous que les objets System.out et System.err sont des objets de type PrintStream (sous-classe de OutputStream) et que l'objet System.in est un objet de type InputStream. Si on regarde un peu les classes du package java.io qui permettent de grer les entres-sorties, on peut les organiser de diffrentes manires. La figure suivante montre les diffrents types d'oprations fournies par ces classes : on retrouve tout d'abord des classes d'entre, c'est--dire qu'elles grent des donnes qui viennent du monde extrieur vers le programme et puis bien entendu des classes de sortie qui grent des donnes qui quittent le programme vers le monde extrieur.

fig j12.4 Organisation des classes du package java.io Une autre distinction qui peut tre faite concerne le type de donnes, comme on l'a vu plus haut, on peut

http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page2.php

Page 2 sur 3

Entres/Sorties : Types de fichier

18/12/07 09:11

manipuler des flux d'octets ou alors directement des flux de caractres. Enfin, la dernire distinction se fait en fonction de la manire dont les donnes sont rcoltes ou envoyes, les data stream se contentent de prendre les donnes simplement tandis que les processing stream vont les modifier pour en obtenir une forme plus volue, on reparlera de cette dernire distinction plus tard. Prcdent Suivant

Copyright 2000-2007 UKO. Toute reproduction strictement interdite sans autorisation du webmaster

Site optimis pour Firefox avec une rsolution 1024x768. Page charge en 0.0659649 secondes

http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page2.php

Page 3 sur 3

Entres/Sorties : Lire un fichier texte

18/12/07 09:11

Accueil >Programmation >Java >Tutoriel >Principal >Chapitre 12 : Fichiers

Lire un fichier texte


Lecture de bas niveau
Commenons par nous intresser la lecture de fichier texte, on utiliser pour ce faire la classe FileReader qui permet de lire un fichier en mode flux de caractres. La premire chose faire est de construire un objet partir de cette classe et le constructeur le plus naturel est celui qui prend un objet File en paramtre. Dans tous les exemples de cette section, on va lire le fichier textfile.
1 2 3 4 5 6 7 8 9 10 } } catch (FileNotFoundException exception) { System.out.println ("Le fichier n'a pas t trouv"); try { FileReader fr = new FileReader (f); File f = new File ("textfile");

listing j12.10 Cration de l'objet FileReader Comme vous le voyez dans le listing prcdent, la cration d'un objet FileReader peut gnrer une erreur de type FileNotFoundException qui est lance si le fichier que vous souhaitez ouvrir n'a pas t trouv. Une fois l'objet cr il est possible de lire le fichier mais les mthodes proposes par la classe FileReader ne sont pas de trs haut niveau et tout ce qu'il est possible de faire est de lire le fichier caractre par caractre en utilisant la mthode read. Attention, cette mthode est susceptible de lancer une exception de type IOException qui apparait lorsqu'une erreur d'entre-sortie se produit comme une panne disque, fichier protg, ...
1 try 2{ 3 4 5} 6 catch (IOException exception) 7{ 8 9} System.out.println ("Erreur lors de la lecture : " + exception.getMessage()); char c = (char) fr.read(); System.out.print (c);

listing j12.11 Lire le premier caractre L'excution de ce programme se contente d'afficher le premier caractre du fichier lu, dans notre cas on voit la console U. Remarquez que la mthode read renvoie un entier de type int qu'il faut convertir en char si on veut le caractre. chaque appel de la mthode, un caractre est lu depuis le fichier et l'appel suivant de la mthode lira donc le caractre suivant. Pour lire tout le fichier, il faut donc faire autant d'appel la mthode read qu'il y a de caractres dans le fichier. Mais comment connaitre ce nombre de caractres ? En fait, on n'a pas besoin de le connaitre, en effet, la mthode read renvoie -1 lorsque la fin du fichier est atteinte et on peut donc afficher tout le contenu du fichier avec une simple boucle while.
1 2 3 4 5 6 7 8 9 }
Page 1 sur 4

try { int c = fr.read(); while (c != -1) { System.out.print ((char) c); c = fr.read();

http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page3.php

Entres/Sorties : Lire un fichier texte

18/12/07 09:11

10 } 11 catch (IOException exception) 12 { 13 14 } System.out.println ("Erreur lors de la lecture : " + exception.getMessage());

listing j12.12 Lire tout un fichier texte Pour terminer, il reste une petite chose faire qu'il ne faut pas oublier, il s'agit de fermer le FileReader, en effet, lorsqu'un programme effectue une opration d'entre-sortie, celui-ci doit demander de l'aide au systme d'exploitation et ce dernier va mobiliser des ressources comme le disque dur, ... Une fois l'opration d'entresortie termine, vous devez le signaler pour que le systme d'opration puisse librer les ressources que vous n'utilisez plus. En Java, il suffit simplement de faire appel la mthode close.
1 fr.close();

listing j12.13 Librer les ressources

Lecture de haut niveau


Lire un fichier en utilisant la classe FileReader n'est pas trs efficace et peut s'avrer couteux en temps tant donn le nombre impressionnant d'appels la mthode read qui sont ncessaires. Heureusement, le package java.io recle de nombreuses autres classes intressantes dont la classe BufferedReader qui permet galement de lire un fichier texte mais offre des fonctions de plus haut niveau qui permettent par exemple de lire le fichier ligne par ligne.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 } 25 catch (FileNotFoundException exception) 26 { 27 28 } System.out.println ("Le fichier n'a pas t trouv"); } } catch (IOException exception) { System.out.println ("Erreur lors de la lecture : " + exception.getMessage()); br.close(); fr.close(); } while (line != null ) { System.out.println (line); line = br.readLine(); try { String line = br.readLine(); try { File f = new File ("textfile"); FileReader fr = new FileReader (f); BufferedReader br = new BufferedReader (fr);

listing j12.14 Lire tout un fichier texte avec la classe BufferedReader La structure est assez semblable l'autre exemple. La premire chose faire est de construire l'objet BufferedReader qui prend un objet de type Reader en paramtre et on lui donne donc un objet FileReader. Ensuite, on peut utiliser la mthode readLine qui va lire une ligne dans le fichier texte et on l'appelle autant de fois qu'il y a de lignes dans le fichier grce un boucle while qui s'arrte ds que la mthode readLine renvoie null, ce qui signifie que la fin du fichier est atteinte. Et on termine par appeler la mthode close pour librer les ressources. Grce la classe BufferedReader, on obtient une lecture du fichier de plus haut niveau puisqu'on peut maintenant lire le fichier ligne par ligne. Une ligne est une squence de caractres qui se termine par un dlimiteur de ligne ( \n, \r ou \r\n) et la mthode readLine renvoie toute une ligne sans le dlimiteur de ligne, c'est pourquoi le programme du listing 12.14 utilise System.out.println pour afficher la ligne sur la sortie standard.
http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page3.php Page 2 sur 4

Entres/Sorties : Lire un fichier texte

18/12/07 09:11

La classe Scanner
Nous avons rencontr au chapitre 4 la classe Scanner et nous l'avons utilise pour lire l'entre standard de manire trs personnalise. Maintenant qu'on a une plus grande connaissance du package java.io, on va pouvoir utiliser ce qu'on a vu pour lire l'entre standard d'une autre manire. De plus, on va galement pouvoir utiliser la classe Scanner pour lire les fichiers d'une autre manire.

Lire l'entre standard


Pour lire l'entre standard, on va pouvoir utiliser un objet de type BufferedReader mais celui-ci prend comme paramtre un objet Reader alors que System.in est un objet de type InputStream et il va donc falloir utiliser un objet InputStreamReader en plus.
1 2 3 4 5 6 7 8 9 10 11 12 } 13 catch (IOException exception){} br.close(); isr.close(); System.out.print ("Tapez une phrase : "); String phrase = br.readLine(); System.out.println ("Vous avez tap <" + phrase + ">"); try { InputStreamReader isr = new InputStreamReader (System.in); BufferedReader br = new BufferedReader (isr);

listing j12.15 Lecture de l'entre standard

Lire un fichier avec Scanner


Rien de plus simple que de lire un fichier avec la classe Scanner, cette classe propose toute une srie de constructeurs pour construire un objet Scanner partir d'un objet File, d'un objet InputStream, ... Une fois l'objet Scanner construit, on peut utiliser toutes les mthodes de cette classe qui sont extrmement riches, rappelez-vous. Imaginons par exemple que l'on aie un fichier qui contienne des noms de personnes avec leur anne de naissance comme ceci : Sbastien 1984 Cdric 1985 John 1976 Avec l'objet Scanner, on va pouvoir lire le fichier de manire trs prcise et par exemple afficher l'ge de chacune des personnes prsente dans le fichier.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 }
Page 3 sur 4

try { File f = new File ("annuaire"); Scanner scanner = new Scanner (f); String name; int bornyear; int curyear = 2007; while (true ) { try { name = scanner.next(); bornyear = scanner.nextInt(); System.out.println (name + " (" + (curyear - bornyear) + " ans)"); } catch (NoSuchElementException exception) { break ; }

http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page3.php

Entres/Sorties : Lire un fichier texte

18/12/07 09:11

24 25 26 } 27 catch (FileNotFoundException exception) 28 { 29 30 } System.out.println ("Le fichier n'a pas t trouv"); scanner.close();

listing j12.16 Lire un fichier avec la classe Scanner L'excution de ce code va produire la console le rsultat suivant : Sbastien (23 ans) Cdric (22 ans) John (31 ans) Avec la classe Scanner, on prcise donc ce que l'on dsire lire, par exemple lire un entier, ou une chaine de caractres, ... Remarquez galement que on lit partir du Scanner avec une boucle infinie while (true) qui s'arrte lorsqu'une exception NoSuchElementException apparait, ce qui signifie qu'il n'y a plus d'lments suivants, c'est--dire qu'on a atteint la fin du fichier. L'utilisation de la classe Scanner offre donc de nombreuses possibilits de trs haut niveau et on peut galement lui fournir un objet bien prcis lors de sa construction, on peut par exemple utiliser un scanner par dessus un BufferedReader. Cette opration qui consiste enchainer plusieurs objets d'affil est appel channeling et est assez courante en programmation oriente objets. On possde des classes de bas niveau qui offre des mthodes simples et brutes et on va construire d'autres classes de plus haut niveau qui utilisent les classes de bas niveau pour offrir un service de plus haut niveau. Dans tous les exemples prsents jusqu' prsent, on crait chaque fois une variable pour chaque objet cr, variable que l'on passait ensuite comme paramtre au constructeur suivant, c'tait leur seul rle mis part l'appel la mthode close qui n'est en fait pas ncessaire, en effet, fermer l'objet de haut niveau va fermer ceux de bas niveau galement. On peut viter de dclarer plein de variables supplmentaires si on le souhaite comme le montre l'exemple suivant.
1 // Version dveloppe 2 File f = new File ("annuaire"); 3 FileReader fr = new FileReader (f); 4 BufferedReader br = new BufferedReader (fr); 5 Scanner scanner = new Scanner (br); 6 7 // Version compacte 8 Scanner scanner = new Scanner (new BufferedReader (new FileReader (new File ("annuaire"))));

listing j12.17 Le channeling d'objets Prcdent Suivant

Copyright 2000-2007 UKO. Toute reproduction strictement interdite sans autorisation du webmaster

Site optimis pour Firefox avec une rsolution 1024x768. Page charge en 0.0487070 secondes

http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page3.php

Page 4 sur 4

Entres/Sorties : crire un fichier texte

18/12/07 09:11

Accueil >Programmation >Java >Tutoriel >Principal >Chapitre 12 : Fichiers

crire un fichier texte


La section prcdente a montr comment faire pour lire un fichier texte depuis un programme. On s'intresse maintenant l'criture de donnes vers un fichier texte, il est intressant d'crire des donnes vers un fichier texte pour pouvoir les stocker lorsque le programme ne tourne plus et pouvoir les rcuprer plus tard ou les changer avec d'autres personnes. Comme vous le verrez, l'criture de fichiers texte est assez similaire leur lecture.

criture de bas niveau


On utilise la classe FileWriter pour crire dans un fichier. Comme pour la lecture, on cre avant tout un objet File qui reprsente le fichier vers lequel on souhaite crire et puis on cr l'objet FileWriter. Notez que si le fichier reprsent par l'objet File n'existe pas, il sera cr automatiquement tandis que s'il existe dj, il sera compltement vid. La classe FileWriter offre des mthodes de bas niveau pour l'criture, on retrouve plusieurs mthodes write pour crire un caractre, une partie de String ou enfin un String complet. Voyons maintenant un exemple qui va crire un tableau de double dans un fichier (ce sont par exemple des donnes mtorologiques) et on va mettre un lment du tableau par ligne du fichier.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 } 16 catch (IOException exception) 17 { 18 19 } System.out.println ("Erreur lors de la lecture : " + exception.getMessage()); fw.close(); } for (double d : data) { fw.write (String.valueOf (d)); fw.write ("\r\n"); try { FileWriter fw = new FileWriter (f); double[] data = {15.9, 21.2, 18.4, 25.4, 31.1}; File f = new File ("temperatures");

listing j12.18 crire un fichier texte avec FileWriter Quelques observations peuvent tre faite partir de cet exemple. Tout d'abord, on n'a qu'une seule exception grer ici, il s'agit de IOException qui apparait lorsqu'une erreur d'entre-sortie se produit. Ensuite, le reste du programme est assez simple, on commence par crer l'objet FileWriter, ensuite on parcoure le tableau et pour chaque lment, on l'crit dans le fichier en le convertissant en String grce la mthode statique String.valueOf et enfin on ajoute un retour la ligne. Pour terminer, on appelle la mthode close pour librer les ressources. Pour l'instant, les donnes sont crites sur le fichier et si celui-ci existait auparavant, il est compltement vid et les nouvelles donnes crasent donc les anciennes. Si l'on souhaite plutt complter un fichier, c'est--dire ouvrir un fichier existant et ajouter des donnes la fin de celui-ci, il faut utiliser un autre constructeur de la classe comme le montre l'exemple suivant et ainsi les donnes crites seront ajoutes la fin du fichier sans craser le contenu dj existant.
1 FileWriter fw = new FileWriter (f, true );

listing j12.19 crire des donnes la fin d'un fichier

criture de haut niveau


Les mthodes proposes par la classe FileWriter sont de bas niveau et il existe d'autres classes qui offrent des mthodes de plus haut niveau qui acclrent et rendent plus facile l'criture vers un fichier texte. On a par
http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page4.php Page 1 sur 2

Entres/Sorties : crire un fichier texte

18/12/07 09:11

exemple la classe BufferedWriter qui offre des mthodes de plus haut niveau et une criture plus rapide et performance. Son fonctionnement est assez similaire la celui de la classe BufferedReader. La classe BufferedWriter permet d'avoir une criture plus performante et propose une mthode supplmentaire qui est la mthode newLine qui ajoute un retour la ligne, en effet, le retour la ligne dans un fichier texte dpend du systme d'exploitation ( \r\n sous Windows, \n sous Unix, ...) et il est donc prfrable d'utiliser cette mthode pour tre portable. En ce qui concerne les mthodes d'criture, toujours aucune mthodes de haut niveau. Il faut donc utiliser une autre classe en plus, par exemple la classe PrintWriter qui se comporte de manire semblable la classe PrintStream dont l'objet System.out est une instance. On peut donc rcrire le programme du listing 12.18 avec ces nouveaux objets pour obtenir une criture plus performante.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 } 15 catch (IOException exception) 16 { 17 18 } System.out.println ("Erreur lors de la lecture : " + exception.getMessage()); pw.close(); } for (double d : data) { pw.println (d); try { PrintWriter pw = new PrintWriter (new BufferedWriter (new FileWriter (f))); double[] data = {15.9, 21.2, 18.4, 25.4, 31.1}; File f = new File ("temperatures");

listing j12.19 crire un fichier texte avec PrintWriter On utilise donc un PrintWriter (pour les mthodes de haut niveau) par dessus un BufferedWriter (pour l'criture rapide) sur un FileWriter (pour l'criture vers un fichier texte). Remarquez qu'avec la classe PrintWriter, on peut utiliser des mthodes de haut niveau comme println qui ajoute une ligne au fichier texte, et il y a d'autres mthodes trs riches comme printf (vu au chapitre 4) pour les sorties formates par exemple. Prcdent Suivant

Copyright 2000-2007 UKO. Toute reproduction strictement interdite sans autorisation du webmaster

Site optimis pour Firefox avec une rsolution 1024x768. Page charge en 0.0377839 secondes

http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page4.php

Page 2 sur 2

Entres/Sorties : Les fichiers binaires

18/12/07 09:12

Accueil >Programmation >Java >Tutoriel >Principal >Chapitre 12 : Fichiers

Les fichiers binaires


Jusqu' prsent, on s'est intress la lecture et l'criture de fichiers textes. On va maintenant survoler un petit peu les fichiers binaires pour voir les classes de la librairie standard de Java qui permettent leur gestion. On ne va pas entrer de trop dans les dtails car il faudrait avant tout mieux comprendre le format binaire. On va simplement se concentrer sur la lecture de fichiers binaires et surtout comprendre les concepts de base. Voyons par exemple comment lire un fichier BMP. Pour rappel, un fichier est constitu de bits (0 ou 1) qui sont groups en blocs de 8 appels des octets (bytes en anglais) et Java propose justement un type primitif cod sur 8 bits, le type primitif byte. Les oprations de lecture et d'criture sur des fichiers binaires consistent donc en la manipulation d'octets, on va avoir des mthodes pour lire et crire une srie d'octets reprsents par des tableaux de byte : byte[].

Le format BMP
Voyons quoi ressemble un fichier BMP, savoir sa structure (Le format BMP BMP est constitue de quatre parties : 1. Entte du fichier 2. Entte de l'image 3. Palette de l'image 4. Corps de l'image On va ici seulement s'intresser l'entte du fichier qui fait 14 octets de long. La figure suivante montre cette entte et son dcoupage. ). On peut voir qu'une image

fig j12.5 Entte d'un fichier BMP On voit que l'entte du fichier est constitue de quatre blocs : 1. Type de fichier (string sur 2 octets) 2. Taille du fichier en octets (entier sur 4 octets) 3. Champ rserv pour utilisation future (sur 4 octets) 4. Offset en octets (entier sur 4 octets) Le premier champ est une chaine de 2 caractres qui reprsente le type de fichier (BM pour un bitmap Windows, ...). Le second champ indique la taille du fichier en octets et est cod comme un entier sur 4 octets. Le troisime champ ne signifie rien, c'est juste une place rserve pour une ventuelle utilisation future et enfin le dernier champ reprsente la position partir de laquelle les informations concernant l'image sont placs dans le fichier.

Lecture de fichier binaire


La premire tape pour lire un fichier binaire est comme toujours de crer l'objet appropri, on va utiliser la classe FileInputStream. Il ne faut pas oublier de grer l'exception FileNotFoundException qui est leve au cas o le fichier n'existe pas et l'exception IOException qui apparait pour tout problme d'entresortie. De plus, on doit galement appeler la mthode close pour librer les ressources quand on a fini de lire le fichier.
1 File file = new File ("logo.bmp");

http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page5.php

Page 1 sur 4

Entres/Sorties : Les fichiers binaires

18/12/07 09:12

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 } 18 catch (FileNotFoundException exception) 19 { 20 21 } System.out.println ("Le fichier n'a pas t trouv"); } } catch (IOException exception) { System.out.println ("Erreur lors de la lecture : " + exception.getMessage()); reader.close(); try { // [...] lecture du fichier try { FileInputStream reader = new FileInputStream (file);

listing j12.20 Lire un fichier binaire avec FileIntputStream Une fois le fichier ouvert, il s'agit maintenant de lire son contenu. On va donc utiliser des tableaux de byte. La premire information lire tient sur 2 octets et est une chaine de caractres reprsentant le type de fichier, on va le lire en utilisant la mthode read qui prend un tableau de byte en paramtre et qui va lire byte.length octets partir du fichier.
1 byte[] data = new byte[2]; 2 reader.read (data); 3 4 String signature = new String (data); 5 System.out.println ("Type : " + signature);

listing j12.21 Lire des octets dans un fichier binaire L'excution de ce code sur un fichier bitmap Windows va afficher la sortie standard : Type : BM C'est donc assez simple de lire un fichier binaire une fois que l'on connait sa structure, il suffit de crer un tableau de byte de la longueur adquate, ensuite on utilise la mthode read pour lire dans le fichier et enfin on transforme le tableau de byte sachant ce qu'il reprsente. Ici, on sait que les deux premiers octets sont une chaine de caractres et donc on cr un objet String. Voyons maintenant la suite, le prochain bloc du fichier est sur 4 octets et reprsente le longueur du fichier.
1 data = new byte[4]; 2 reader.read (data); 3 4 int size = byteArrayToInt (data); 5 System.out.println ("Taille : " + size + " octets");

listing j12.22 Lire des octets dans un fichier binaire (2) L'excution de ce code sur le fichier logo.bmp va afficher sur la sortie standard : Taille : 16994 octets La premire partie du code est pareille que prcdemment sauf que cette fois-ci on lit 4 octets partir du fichier. C'est la seconde partie qui diffrent, cette fois-ci on sait que les 4 octets lus sont en fait un entier de type int et il va donc falloir convertir le tableau de byte en un int mais il n'existe pas de mthodes toute faite dans la librairie standard Java et on utilise donc notre propre mthode prive prsente au listing suivant.
1 2 3 4 5 6 public static int byteArrayToInt (byte[] b) { int value = 0; for (int i = 0; i < 4; i++) { int n = (b[i] < 0 ? (int) b[i] + 256 : (int)b[i]) << (8 * i);

http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page5.php

Page 2 sur 4

Entres/Sorties : Les fichiers binaires

18/12/07 09:12

7 8 9 10 } }

value += n; return value;

listing j12.23 Convertir un tableau de byte vers un int Nous ne donnerons ici aucune explications propos de cette mthode, en effet, il faudrait avant tout bien comprendre le monde binaire et les diffrents oprateurs qui y sont attachs. En ce qui concerne la fin de la lecture de l'entte, il faut passer les quatre octets suivants car ils ne servent rien et on peut le faire avec la mthode skip. Ensuite les quatre dernier octets reprsentent l'offset. Enfin, il faut encore lire tout le fichier compltement pour finalement afficher l'image l'cran par exemple.
1 reader.skip (4); 2 3 data = new byte[4]; 4 reader.read (data); 5 6 int offset = byteArrayToInt (data); 7 System.out.println ("Offset : " + offset + " octets");

listing j12.24 Lire des octets dans un fichier binaire (3)

Lecture de plus haut niveau


D'autres classes existent dans la librairie standard Java et offrent des mthodes de plus haut niveau pour la lecture de fichier binaire. On retrouve par exemple la classe DataInputStream qui permet de directement lire des types primitifs depuis un fichier binaire. Le seul soucis est que l'on ne contrle pas la manire d'interprter les octets aussi finement qu'avec FileInputStream. On utilisera donc la classe DataInputStream pour lire des fichiers qui ont t crit avec la classe DataOutputStream. Voyons un exemple qui stocke un tableau de double dans un fichier binaire et qui va ensuite le lire. On stocke en premire position un entier qui indique la taille du tableau, ce nombre sera utile pour lire le fichier par la suite.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 } 29 catch (IOException exception) 30 { 31 32 } System.out.println ("Erreur lors de la lecture : " + exception.getMessage()); System.out.println (Arrays.toString (readdata)); reader.close(); } // Lire le fichier DataInputStream reader = new DataInputStream (new FileInputStream (file)); int size = reader.readInt(); double[] readdata = new double[size]; for (int i = 0; i < size; i++) { readdata[i] = reader.readDouble(); } writer.close(); writer.writeInt (data.length); for (double d : data) { writer.writeDouble (d); try { // crire le fichier DataOutputStream writer = new DataOutputStream (new FileOutputStream (file)); double[] data = {15.9, 21.2, 18.4, 25.4, 31.1}; File file = new File ("temperatures_binary");

http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page5.php

Page 3 sur 4

Entres/Sorties : Les fichiers binaires

18/12/07 09:12

listing j12.25 Lire et crire dans un fichier binaire Pour crire dans le fichier on utilise donc la classe DataOutputStream et les mthodes writeXXX o XXX reprsente un type de donne. Ensuite, on peut lire le fichier avec la classe DataInputStream et les mthode readXXX. Le fichier crit est bien lu correctement comme en tmoigne le rsultat imprim sur la sortie standard : [15.9, 21.2, 18.4, 25.4, 31.1] Un avantage des fichiers binaires est que l'on peut directement crire des types primitifs et les rcuprer. Imaginons que l'on souhaite crire des fichiers contenant beaucoup d'information numrique comme une image par exemple, si on devait le faire avec un fichier texte, lors de la lecture, il faudrait convertir toutes les chaines de caractres lues ce qui peut consommer pas mal de temps. Le choix du type de fichier que l'on va choisir pour crire une certain information dpend donc grandement de l'information elle mme. Prcdent Suivant

Copyright 2000-2007 UKO. Toute reproduction strictement interdite sans autorisation du webmaster

Site optimis pour Firefox avec une rsolution 1024x768. Page charge en 0.0719531 secondes

http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page5.php

Page 4 sur 4

Entres/Sorties : Srialisation

18/12/07 09:12

Accueil >Programmation >Java >Tutoriel >Principal >Chapitre 12 : Fichiers

Srialisation
Jusqu' prsent, on s'est concentr sur les fichiers textes dans lesquels on crivait des chaines de caractres et sur les fichiers binaires o on pouvait crire des types primitifs, mais on utilise la programmation oriente objets et on aimerait bien pouvoir crire directement des objets dans un fichier pour pouvoir les rcuprer plus tard. Et bien, c'est tout fait possible grce au mcanisme de srialisation qui permet de sauvegarder un objet dans un fichier, c'est--dire son tat en fait, et puis on peut rcuprer l'objet plus tard tel qu'il tait avant la sauvegarde.

Principe
Supposons que l'on possde une classe reprsentant une personne. La classe possde quatre variable d'instance reprsentant le nom, le prnom, la date de naissance et l'ge de la personne. L'ge est bien entendu une information redondante mais il est stock pour viter la mthode getAge de le recalculer chaque fois. Le listing suivant prsente la classe en question.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 } } public int getAge() { return age; } public GregorianCalendar getBirthdate() { return birthdate; } public String getLastname() { return lastname; } public String getFirstname() { return firstname; } public Person (String first, String last, GregorianCalendar birthdate) { firstname = first; lastname = last; this .birthdate = birthdate; age = new GregorianCalendar().get (YEAR) - birthdate.get (YEAR); public class Person { private String firstname, lastname; private GregorianCalendar birthdate; private int age; import static java.util.GregorianCalendar.YEAR; import java.util.GregorianCalendar;

listing j12.20 La classe Person Imaginons que l'on souhaite sauvegarder dans un fichier une instance de cette classe pour pouvoir la rcuprer plus tard, si on veut le faire manuellement, il va falloir stocker toutes les informations ncessaires la
http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page6.php Page 1 sur 4

Entres/Sorties : Srialisation

18/12/07 09:12

reconstruction de l'objet, c'est--dire le nom, le prnom et la date de naissance. crire le nom et le prnom, c'est facile, mais pour la date de naissance, c'est tout de suite plus dlicat. Java offre un mcanisme appel srialisation qui permet de sauvegarder un objet dans un fichier et de le rcuprer. En somme, la srialisation permet de sauvegarder un objet et son tat, c'est--dire ses variables d'instance. Tout objet qui peut tre srialis doit implmenter l'interface Serializable. Cette interface ne contient aucune mthodes implmenter, elle agit simplement comme un marqueur, toute classe implmentant cette interface signale simplement que ses instances peuvent tre srialises. Notre classe Person doit donc implmenter cette interface. Commenons simplement par crer un objet Person et l'afficher la console.
1 GregorianCalendar date = new GregorianCalendar (1976, 0, 1); 2 Person p = new Person ("John", "Doe", date); 3 System.out.println (p);

listing j12.21 Cration d'un objet Person Si on ajoute la mthode toString la classe Person, l'excution de ce programme pourrait par exemple afficher la sortie standard la ligne suivante (essayez d'crire la mthode toString pour vous exercer) : John Doe, n le 01/01/76 (31 ans)

Srialisation
Maintenant, on souhaite sauvegarder cet objet dans un fichier et pour ce faire, on va utiliser la classe ObjectOutputStream par dessus un FileOutputStream, en effet, les fichiers gnrs sont des fichiers binaires.
1 2 3 4 5 6 7 8 9 11 12 } } catch (IOException exception) System.out.println ("Erreur lors de l'criture : " + exception.getMessage()); try { ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream (f)); oos.writeObject (p); oos.close(); File f = new File ("person.objet");

10 {

listing j12.22 Srialisation d'un objet L'criture est assez simple, on utilise simplement la mthode writeObject de la classe ObjectOutputStream qui permet d'crire un objet vers la sortie. Outre cette mthode, la classe ObjectOutputStream propose aussi toute une srie de mthode pour stocker des types primitifs, des tableaux de byte ou des String. Et voil, c'est tout, l'objet est maintenant sauvegard dans le fichier person.objet.

Dsrialisation
Comment rcuprer l'objet partir du fichier ? Toujours aussi simple, on utilise cette fois-ci un objet ObjectInputStream par dessus un FileInputStream et on invoque la mthode readObject pour rcuprer le fichier.
1 2 3 4 5 6 7 8 9 11 12 } 13 catch (IOException exception) } catch (ClassNotFoundException exception) System.out.println ("Impossible de lire l'objet : " + exception.getMessage()); System.out.println (p2); try { ObjectInputStream ois = new ObjectInputStream (new FileInputStream (f)); Person p2 = (Person) ois.readObject(); ois.close();

10 {

http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page6.php

Page 2 sur 4

Entres/Sorties : Srialisation

18/12/07 09:12

14 { 15 16 } System.out.println ("Erreur lors de l'criture : " + exception.getMessage());

listing j12.23 Dsrialisation d'un objet Et voil, on rcupre l'objet partir du fichier grce la mthode readObject qui renvoie un objet de type Object que l'on doit donc convertir en objet de type Person et si on l'affiche la console, on voit qu'on a exactement le mme objet qu'avant srialisation. Remarquez qu'il faut grer une exception supplmentaire, l'exception ClassNotFoundException qui apparait si la classe correspondant l'objet srialis lu n'est pas trouve par la machine virtuelle Java. Enfin, si la conversion n'est pas possible, une erreur d'excution de type ClassCastException est leve.

Interface Serializable
Sauvegarder un objet revient sauvegarder toutes ses variables d'instances. Pour des variables d'instances de type primitif, c'est simple mais si un objet possde des variables d'instance de type objet, elles seront aussi sauvegardes, c'est--dire que leurs variables d'instances seront sauvegardes, ... Le mcanisme de srialisation sauvegarde donc automatiquement tout l'tat de l'objet, la machine virtuelle Java procde une copie en profondeur. Bien entendu, il faudra alors que tous les objets impliqus de manire directe ou indirecte implmentent l'interface Serializable, sans quoi une erreur apparaitra lors de l'criture, une exception NotSerializableException sera leve.

Le mot rserv transient


Dans notre exemple, la classe Person possde une variable d'instance redondante qui reprsente l'ge et on aimerait pouvoir ne pas la stocker dans le fichier lors de la srialisation pour conomiser un peu de place. C'est trs facile faire, il suffit d'ajouter le mot rserv transient lors de la dclaration de la variable. Les variables d'instance marques transient ne sont pas sauvegardes dans le fichier lors de la srialisation.
1 private transient int age;

listing j12.24 Le mot rserv transient Si on excute nouveau notre programme, on se rend compte qu'il y a un problme, en effet, voici ce qu'on peut lire sur la sortie standard : John Doe, n le 01/01/76 (31 ans) John Doe, n le 01/01/76 (0 ans) Le problme est que lors de la dsrialisation, comme on a pas stock la variable d'instance age dans le fichier et comme le constructeur de la classe n'est pas invoqu lors d'une dsrialisation, on se retrouve avec la variable d'instance age qui n'est pas initialise et possde donc la valeur par dfaut pour les int, savoir 0.

Lecture et criture personnalise


Lorsqu'un objet srialisable est sauvegard vers un fichier, ses variables d'instances qui ne sont pas marques avec le mot rserv transient sont sauvegardes dans le fichier. Ce sont ces mmes variables qui seront initialises avec les valeurs sauvegardes lors de la lecture. Il est possible de modifier ce comportement en implmentant deux mthodes spciales dans les classes srialisable, ce sont les mthodes writeObject et readObject.
1 private void writeObject (ObjectOutputStream stream) throws IOException; 2 3 private void readObject (ObjectInputStream stream) throws IOException, ClassNotFoundException;

listing j12.25 Les mthodes writeObject et readObject Grce ces mthodes, on va pouvoir rsoudre notre problme concernant la variable d'instance age qui n'est pas initialise. On va simplement implmenter la mthode readObject. La mthode va commencer par dsrialiser l'objet de manire normale en appelant la mthode defaultReadObject sur le paramtre stream et ensuite, on peut initialiser notre variable d'instance comme montr au listing suivant.
1 private void readObject (ObjectInputStream stream) throws IOException, ClassNotFoundException 2{ 3 4 5} stream.defaultReadObject(); age = new GregorianCalendar().get (YEAR) - birthdate.get (YEAR);

http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page6.php

Page 3 sur 4

Entres/Sorties : Srialisation

18/12/07 09:12

listing j12.26 Utiliser la mthode readObject L'implmentation de ces deux mthodes s'avre galement utile dans d'autres cas, par exemple si vous voulez pouvoir srialiser une classe qui contient des variables d'instance non srialisable. On verra quelques autres exemples dans le cadre des exercices. Prcdent Suivant

Copyright 2000-2007 UKO. Toute reproduction strictement interdite sans autorisation du webmaster

Site optimis pour Firefox avec une rsolution 1024x768. Page charge en 0.0611849 secondes

http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page6.php

Page 4 sur 4

Entres/Sorties : Libration des ressources

18/12/07 09:12

Accueil >Programmation >Java >Tutoriel >Principal >Chapitre 12 : Fichiers

Libration des ressources


Terminons ce chapitre consacr aux entres/sorties en Java et plus particulirement la gestion de fichiers en revenant sur le problme de libration des ressources. Pour rappel, chaque fois qu'on a utilis des classes pour effectuer des oprations d'entres/sorties, on devait appeler la mthode close pour librer les ressources alloues par le systme d'exploitation. Repartons d'un exemple simple de lecture d'un fichier texte et tentons de lire un fichier qui n'existe pas.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 } 22 catch (FileNotFoundException exception) 23 { 24 25 } System.out.println ("Le fichier n'a pas t trouv"); } } catch (IOException exception) { System.out.println ("Erreur lors de la lecture : " + exception.getMessage()); } reader.close(); System.out.println ("Le fichier est bien ferm"); try { int c = reader.read(); while (c != -1) { System.out.println ((char) c); c = reader.read(); File f = new File ("existepas"); try { FileReader reader = new FileReader (f);

listing j12.27 Lecture d'un fichier texte Le fichier n'a pas t trouv l'excution de ce programme, l'exception FileNotFoundException est leve tant donn que le fichier n'existe pas. Dans ce cas, la mthode close n'est pas appele et les ressources ne sont pas libres mais ce n'est pas grave tant donn qu'aucun fichier n'est ouvert et donc aucune ressources ne sont alloues.

Bloc try-finally
Imaginons maintenant qu'une erreur se produise lors de la lecture, c'est--dire lors de l'appel la mthode read. Le programme est par exemple en train de lire un fichier depuis une cl USB et quelqu'un la retire violemment du port USB pendant la lecture, une exception IOException est leve. L'exception tant leve, le flux de contrle saute au bloc catch grant l'erreur et le reste du bloc try est ignor, et donc la mthode close n'est pas appele. On pourrait se dire, il suffit d'appeler la mthode close chaque point de sortie possible du programme mais c'est vraiment lourd et une meilleure approche serait d'utiliser la clause finally vue au chapitre prcdent. La structure gnrale d'un programme utilisant des ressources extrieures est prsent au listing suivant.
1 2 3 4 5 6 7 8 9 10 } } finally { // (3) Libration des ressources try { // (2) Utilisation de la ressource avec gestion des erreurs // (1) Cration de la ressource

listing j12.28 Structure d'un programme exploitant des ressources extrieures

http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page7.php

Page 1 sur 2

Entres/Sorties : Libration des ressources

18/12/07 09:12

En utilisant cette structure, les ressources seront libres dans tous les cas, savoir si une exception est leve, si une exception est propage ou si l'instruction return est utilise dans le bloc try. Pour rsoudre notre problme de manire propre, on va donc placer la lecture du fichier dans un bloc tryfinally dans une nouvelle mthode part. Ainsi, on conserve la gestion des exceptions et en plus on a la libration des ressources assure.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 } } } finally { reader.close(); System.out.println ("-> Le fichier est bien ferm"); } System.out.println(); private static void printFileContent (File f) throws FileNotFoundException, IOException { FileReader reader = new FileReader (f); try { int c = reader.read(); while (c != -1) { System.out.print ((char) c); c = reader.read();

listing j12.29 Lecture d'un fichier texte avec libration correcte des ressources La mthode dclare donc les deux exceptions qui sont susceptibles d'tre leves et utilise un bloc tryfinally pour librer les ressources dans tous les cas. Les exceptions sont propages et peuvent donc toujours tre gre plus haut niveau. Le listing suivant montre l'appel vers cette mthode avec la gestion des exceptions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 } } } catch (IOException exception) { System.out.println ("Erreur lors de la lecture : " + exception.getMessage()); } catch (FileNotFoundException exception) { System.out.println ("Le fichier n'a pas t trouv"); public static void main (String[] args) { File f = new File ("textfile"); try { printFileContent (f);

listing j12.30 Utilisation de la mthode printFileContent Vous vous demandez peut-tre pourquoi on n'a pas utilis un bloc try-catch-finally pour rsoudre le problme de la libration des ressources, la rponse est assez simple, si on avait utilis un tel bloc, on aura du ajouter en plus un try-catch autour de la mthode close dans le bloc finally tant donn que la mthode close est susceptible de lever une exception de type IOException. Ce problme est abord dans les exercices. Prcdent

Copyright 2000-2007 UKO. Toute reproduction strictement interdite sans autorisation du webmaster

Site optimis pour Firefox avec une rsolution 1024x768. Page charge en 0.0744979 secondes

http://www.ukonline.be/programmation/java/tutoriel/chapitre12/page7.php

Page 2 sur 2

Das könnte Ihnen auch gefallen