Vous êtes sur la page 1sur 6

Utilisation des chiers texte en Java

NFA005 2 mars 2009

1 Introduction
Les chiers sont des structures de donnes stockes sur disque. A la diffrence des donnes gres en mmoire par les programmes (entiers, boolens, nombres rels, tableaux, objets de diffrents types, etc), qui sont perdues la n du programme, les chiers sont des structures de donnes persistantes, quon peut retrouver la prochaine fois que le programme sera excute. Au niveau physique, un chier est compos dune suite de blocs disque de taille constante, gr par le systme dexploitation, qui offre aux programmes une vue logique du chier. Au niveau logique, le chier est une suite doctets, qui reprsentent des informations de diffrents types : entiers, boolens, nombres rels, tableaux, objets, etc. Pour pouvoir interprter ces informations lors de la lecture du chier, il faut connatre le type dinformation qui y a t crit. Les chiers texte sont un cas particulier de chier, o toute linformation est reprsente par une suite de caractres. On peut voir un chier texte comme une longue chane de caractres stocke sur disque. Les lignes successives de texte sont spares par un ou plusieurs caractres de n de ligne : la squence de deux caractres \r et \n en windows. le caractre \n en unix et Mac Intosh. le caractre \r sur les anciens systme Apple. Une diffrence importante entre les chiers textes et les chiers binaires ordinaires est que toute donne est reprsente par sa chane de caractres dafchage. Par exemple le boolean true, qui normalement est reprsent sur un octet, apparatra dans le chier texte en tant que chane de caractres true. Un entier, qui occupe normalement 4 octets, sera reprsent par la suite de caractres chiffres qui le composent. Par exemple lentier 125 sera reprsent par la chane de caractres 125, tandis que lentier -34567 par la chane -34567. Donc des entiers diffrents, qui en mmoire ont la mme taille (4 octets), auront des tailles diffrentes dans le chier texte. Il faut noter que des perturbations lies au codage des caractres peuvent survenir. Il existe en effet deux grands codages : le codage ASCII qui est utilis par les systmes dexploitation actuels (unix, windows). Il code chaque caractre avec un octet. Il existe plusieurs variantes permettant de reprsenter des jeux de caractres diffrents, notamment pour ce qui concerne les accents. le codage unicode, qui est utilis par Java. Il nen existe quune version unique, mais les polices disponibles sur un ordinateur donn ne couvrent pas tous les caractres unicode. Les caractres sont cods sur deux octets. le codage UTF-8 est un codage intermdiaire entre les deux prcdents, permettant de stocker de lunicode dans un systme bas sur lASCII. Sur un ordinateur bien congur, il nest pas ncessaire de connatre le codage pour faire fonctionner les programmes java. En revanche, il peut y avoir des difcults relire sur un ordinateur donn 1

2 LECTURE DUN FICHIER TEXTE

des chiers crs sur un autre ordinateur. Java offre une large palette de classes et mthodes pour utiliser les chiers, dont nous prsenterons ici seulement les plus importantes, travers des exemples. Toutes ces classes se trouvent dans le paquetage java.io, qui doit tre import dans le programme qui utilise les chiers.

2 Lecture dun chier texte


Lexemple suivant demande lutilisateur le nom dun chier texte, louvre ensuite en lecture, le lit ligne par ligne et lafche lcran. import java . io . ; class LectureFichier { p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) { T e r m i n a l . e c r i r e S t r i n g ( "Nom f i c h i e r : " ) ; S t r i n g nomFichier = Terminal . l i r e S t r i n g ( ) ; try { F i l e R e a d e r f r = new F i l e R e a d e r ( n o m F i c h i e r ) ; B u f f e r e d R e a d e r b r = new B u f f e r e d R e a d e r ( f r ) ; S t r i n g l i g n e = br . readLine ( ) ; w h i l e ( l i g n e != n u l l ) { Terminal . e c r i r e S t r i n g l n ( l i g n e ) ; l i g n e = br . readLine ( ) ; } br . cl ose ( ) ; } catch ( FileNotFoundException e ){ T e r m i n a l . e c r i r e S t r i n g l n ( " F i c h i e r non t r o u v " ) ; } catch ( IOException e ){ T e r m i n a l . e c r i r e S t r i n g l n ( " P r o b l m e l a l e c t u r e du f i c h i e r " ) ; } } } Quelques explications : Linstruction import java.io.* permet dutiliser les classes daccs aux chiers texte. Lobjet de type FileReader permet de lire un chier texte caractre par caractre. Si le chier dont le nom est donne en paramtre au constructeur nest pas trouv, lexception FileNotFoundException est leve. Lobjet de type BufferedReader utilise un tampon mmoire pour viter daccder le disque chaque fois quune lecture est demande. Il optimise les performances et offre des fonctionnalits de lecture plus avances, comme la lecture ligne par ligne par la mthode readLine(). Quand lappel readLine() retourne null, la n du chier a t atteinte. A la n de la lecture du chier, il faut fermer le BufferedReader avec la mthode close(). Les mthodes readLine() et close() peuvent produire une exception IOException en cas de problme. Cela narrive gnralement pas, mais il faut traiter quand mme cette exception

3 UTILISER LES CHANES DE CARACTRES LUES PARTIR DU FICHIER TEXTE


dans le programme.

3 Utiliser les chanes de caractres lues partir du chier texte


Il est souvent ncessaire dutiliser les chanes de caractres lues partir du chier texte pour en extraire des parties, pour les convertir en des donnes dautres types, etc. Lexemple suivant ralise deux traitements de ce genre. Le premier prend une chane constitue dentiers spars par un ou plusieurs espaces, extrait les sous-chanes de ces entiers, les convertit en entiers, calcule et afche leur somme. Le second prend une chane o des sous-chanes sont spars par un caractre #, extrait et afche ces sous-chanes. class ExtractionString { p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) { S t r i n g ex1 = " 23 17 5 2 " ; try { i n t somme = 0 ; S t r i n g r e s t e = ex1 . t r i m ( ) ; while ( r e s t e . length () >0){ i n t pos = r e s t e . i n d e x O f ( ) ; String valString ; i f ( pos >=0) v a l S t r i n g = r e s t e . s u b s t r i n g ( 0 , pos ) ; else valString = reste ; i n t val = Integer . p arse Int ( valS tring ) ; somme = somme + v a l ; i f ( pos >=0) r e s t e = r e s t e . s u b s t r i n g ( pos ) . t r i m ( ) ; else reste = ""; } T e r m i n a l . e c r i r e S t r i n g l n ( " Somme = " + somme ) ; } c a t c h ( NumberFormatException e ){ Terminal . e c r i r e S t r i n g l n ( " E n t i e r i n c o r r e c t " ) ; } S t r i n g ex2 = " t e x t e # 15 # f i n a l " ; S t r i n g [ ] p a r t s = ex2 . s p l i t ( " # " ) ; f o r ( i n t i = 0 ; i < p a r t s . l e n g t h ; i ++) Terminal . e c r i r e S t r i n g l n ( p a r t s [ i ] ) ; } } Quelques explications : La mthode trim() de String retourne une chane o les espaces au dbut et la n de la chane ont t limins. La mthode indexOf de String prend un caractre en paramtre et retourne la premire position o lon trouve ce caractre dans la chane (ou -1 si le caractre ne sy trouve pas).

4 LECTURE DUN FICHIER TEXTE CARACTRE PAR CARACTRE

La mthode substring de String extrait une sous-chane de la chane. Elle prend un ou deux paramtres : le premier est la position de dbut et le second (sil existe) est la position tout de suite aprs la sous-chane extraire. Si le second paramtre nest pas prcis, on extrait jusqu la n de la chane. La mthode parseInt de la classe Integer, transforme la chane passe en paramtre en une valeur entire. Si la chane nest pas un entier correct, lexception NumberFormatException est leve. La technique dextraction des entiers de la chane est la suivante. On limine les espaces au dbut et la n avec trim, ensuite on cherche le premier espace. Sil existe (pos >= 0, on extrait la sous-chane entier en sarrtant pos, sinon cest toute la chane (reste) qui reprsente lentier. On transforme en entier, on le rajoute la somme, ensuite on calcule le reste de la chane et tout est rpt jusqu ce que le reste devient vide. Pour le second cas, on utilise la mthode split de String. Elle prend en paramtre une chane de caractres qui sert de dlimiteur aux sous-chanes extraire. Elle retourne un tableau de sous-chanes, extraites de la chane initiale par rapport au dlimiteur. Dans notre exemple, le rsultat contient 3 sous-chanes : " texte", " 15 " et " final".

4 Lecture dun chier texte caractre par caractre


La lecture dun chier peut se faire caractre par caractre au lieu de se faire ligne par ligne. Il faut pour cela utiliser la mthode read au lieu de la mthode readLine. Les oprations douverture et de fermeture du chier sont identiques. La mthode read ne prend pas de paramtre et renvoie un entier (type int). Cet entier est -1 sil ny a plus de caractre lire dans le chier (la n de chier a t atteinte). Sinon il contient le code du caractre dans la table unicode. On peut le convertir en caractre au moyen dune conversion explicite de type. Voici le programme dafchage dun chier. import java . io . ; class LectureFichierBis { p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) { T e r m i n a l . e c r i r e S t r i n g ( "Nom f i c h i e r : " ) ; S t r i n g nomFichier = Terminal . l i r e S t r i n g ( ) ; try { F i l e R e a d e r f r = new F i l e R e a d e r ( n o m F i c h i e r ) ; B u f f e r e d R e a d e r b r = new B u f f e r e d R e a d e r ( f r ) ; i n t c = br . read ( ) ; w h i l e ( c != 1){ Terminal . e c r i r e C h a r ( ( char ) c ) ; c = br . read ( ) ; } br . cl ose ( ) ; } catch ( FileNotFoundException e ){ T e r m i n a l . e c r i r e S t r i n g l n ( " F i c h i e r non t r o u v " ) ; }

5 ECRITURE DUN FICHIER TEXTE

catch ( IOException e ){ T e r m i n a l . e c r i r e S t r i n g l n ( " P r o b l m e l a l e c t u r e du f i c h i e r " ) ; } } } On voit dans ce programme un exemple de conversion dentier en caractre : (char) c. Il est parfois plus agrable de faire une lecture caractre par caractre que ligne par ligne.

5 Ecriture dun chier texte


Lexemple suivant demande lutilisateur le nom dun chier texte, louvre ensuite en criture et y crit plusieurs informations. import java . io . ; class EcritureFichier { p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) { T e r m i n a l . e c r i r e S t r i n g ( "Nom f i c h i e r : " ) ; S t r i n g nomFichier = Terminal . l i r e S t r i n g ( ) ; try { F i l e W r i t e r fw = new F i l e W r i t e r ( n o m F i c h i e r ) ; B u f f e r e d W r i t e r bw = new B u f f e r e d W r i t e r ( fw ) ; P r i n t W r i t e r pw = new P r i n t W r i t e r ( bw ) ; pw . p r i n t ( 1 2 5 ) ; pw . p r i n t ( " & " ) ; pw . p r i n t l n ( 3 . 1 4 ) ; pw . p r i n t ( " t e x t e " ) ; pw . c l o s e ( ) ; } catch ( IOException e ){ T e r m i n a l . e c r i r e S t r i n g l n ( " P r o b l m e l c r i t u r e du f i c h i e r " ) ; } } } Quelques explications : Lobjet de type FileWriter permet dcrire un chier texte caractre par caractre. A la diffrence de FileReader, lexception FileNotFoundException nest pas leve. Si le chier existe dj, il sera cras, sil nexiste pas, il sera cr. Par contre, lexception IOException peut tre leve si on ne peut pas crer le chier (disque plein, pas de droits dcriture, etc). Lobjet de type BufferedWrite apporte la mme optimisation en criture que BufferedReader en utilisant un tampon mmoire. Par contre, les fonctionalits dcriture restent de bas niveau, do le besoin dun objet PrintWriter. Lobjet PrintWriter offre les mthodes print et println avec un paramtre de nimporte quel type simple (entier, caractre, boolean, double) ou chane de caractres. Elles fonctionnent de la mme faon que les mthodes ecrireXXX et ecrireXXXln de la classe Terminal.

5 ECRITURE DUN FICHIER TEXTE

A la n de lcriture du chier, il faut fermer le PrintWriter avec la mthode close(), qui peut produire une exception IOException.

Vous aimerez peut-être aussi