2I002
FLUX, FICHIERS
Vincent Guigue
Entrées/Sorties
Les entrées et sorties sont gérées séparément:
IN :
OUT :
JAVA = panoplie d’outils pour communiquer dans les deux sens avec toutes sortes de sources
2i002 – Flux 2/39
Basic I/O
Définition
Les flux (=stream) désignent les entrées/sorties des programmes (autre que les arguments du main)
Il s’agit d’outils essentiels dès que l’on souhaite Lire/écrire des fichiers
Sauver les paramètres d’un programme (=écrire un fichier!) Communiquer avec d’autres postes de travail (en réseau) Travailler à plusieurs sur un projet (=svt gérer des fichiers) Lire/écrire dans des BD
Saisie clavier
Ecriture console
Fichiers: lecture
Plan général
1
Fichiers: lire les noms, vérifier l’existence, vérifier la possibilité d’écriture...
Equivalent des fonctions dir, cd, ... Mais à l’intérieur de JAVA
2
Une fois le fichier ciblé, l’ouvrir et lire ce qu’il y a dedans
3
Créer un fichier et/ou écrire dedans
4
... D’autres choses se gèrent comme les fichiers
Clavier, Réseau...
Gérer les fichiers sur le disque dur
Classe File
Cette classe permet de gérer les fichiers:
test d’existance
distinction fichier/répertoire copie/effacement
...
boolean canExecute() boolean canRead() boolean canWrite() boolean delete() boolean isDirectory() boolean isFile() File[] listFiles() boolean mkdir()
Nombreuses opérations très intéressantes concernant la manipulation des fichiers
2i002 – Flux 5/39
Lecture de fichiers
1
File: désigner un fichier
2
FileInputStream: création de cet objet = ouverture en lecture du fichier
Des exceptions à gérer
Penser à fermer les fichiers ouverts
1 F i l e I n p u t S t r e a m i n = n u l l;
2 F i l e f = new F i l e (" x a n a d u . t x t ") ;
3 t r y {
4 i n = new F i l e I n p u t S t r e a m ( f ) ; // o u v e r t u r e du f i c h i e r
5 // Throws : F i l e N o t F o u n d E x c e p t i o n : => t r y / c a t c h
6
7 // OPERATIONS DE LECTURE
8
9 }
10 } f i n a l l y {
11 i f ( i n != n u l l) {
12 i n . c l o s e ( ) ;
13 }
14 }
Les petits pièges... La fermeture des fichiers
1
Toujours fermer un fichier ouvert...
1 t r y { F i l e I n p u t S t r e a m i n = new F i l e I n p u t S t r e a m (
2 new F i l e ( f i l e n a m e ) ) ;
3 . . . // LECTURE
4 i n . c l o s e ( ) ;
5 }c a t c h( . . . ) { . . . }
2
Même s’il y a des erreurs pendant la lecture !
1 t r y { F i l e I n p u t S t r e a m i n = new F i l e I n p u t S t r e a m (
2 new F i l e ( f i l e n a m e ) ) ;
3 . . . // LECTURE
4 i n . c l o s e ( ) ;
5 }c a t c h( . . . ) { in.close(); }
3
Mais ça ne compile pas !
1 FileInputStream in = null;
2 t r y { i n = new F i l e I n p u t S t r e a m (new F i l e ( f i l e n a m e ) ) ;
3 . . . // LECTURE
4 i n . c l o s e ( ) ;
5 }c a t c h( . . . ) { i n . c l o s e ( ) ; }
4
Plus élégant: lignes 4-5 ⇒ finally{in.close()}
2i002 – Flux 7/39
Les petits pièges... La fermeture des fichiers
1
Toujours fermer un fichier ouvert...
1 t r y { F i l e I n p u t S t r e a m i n = new F i l e I n p u t S t r e a m (
2 new F i l e ( f i l e n a m e ) ) ;
3 . . . // LECTURE
4 i n . c l o s e ( ) ;
5 }c a t c h( . . . ) { . . . }
2
Même s’il y a des erreurs pendant la lecture !
1 t r y { F i l e I n p u t S t r e a m i n = new F i l e I n p u t S t r e a m (
2 new F i l e ( f i l e n a m e ) ) ;
3 . . . // LECTURE
4 i n . c l o s e ( ) ;
5 }c a t c h( . . . ) { in.close(); }
3
Mais ça ne compile pas !
1 FileInputStream in = null;
2 t r y { i n = new F i l e I n p u t S t r e a m (new F i l e ( f i l e n a m e ) ) ;
3 . . . // LECTURE
4 i n . c l o s e ( ) ;
5 }c a t c h( . . . ) { i n . c l o s e ( ) ; }
4
Plus élégant: lignes 4-5 ⇒ finally{in.close()}
Les petits pièges... La fermeture des fichiers
1
Toujours fermer un fichier ouvert...
1 t r y { F i l e I n p u t S t r e a m i n = new F i l e I n p u t S t r e a m (
2 new F i l e ( f i l e n a m e ) ) ;
3 . . . // LECTURE
4 i n . c l o s e ( ) ;
5 }c a t c h( . . . ) { . . . }
2
Même s’il y a des erreurs pendant la lecture !
1 t r y { F i l e I n p u t S t r e a m i n = new F i l e I n p u t S t r e a m (
2 new F i l e ( f i l e n a m e ) ) ;
3 . . . // LECTURE
4 i n . c l o s e ( ) ;
5 }c a t c h( . . . ) { in.close(); }
3
Mais ça ne compile pas !
1 FileInputStream in = null;
2 t r y { i n = new F i l e I n p u t S t r e a m (new F i l e ( f i l e n a m e ) ) ;
3 . . . // LECTURE
4 i n . c l o s e ( ) ;
5 }c a t c h( . . . ) { i n . c l o s e ( ) ; }
4
Plus élégant: lignes 4-5 ⇒ finally{in.close()}
2i002 – Flux 7/39
Les petits pièges... La fermeture des fichiers
1
Toujours fermer un fichier ouvert...
1 t r y { F i l e I n p u t S t r e a m i n = new F i l e I n p u t S t r e a m (
2 new F i l e ( f i l e n a m e ) ) ;
3 . . . // LECTURE
4 i n . c l o s e ( ) ;
5 }c a t c h( . . . ) { . . . }
2
Même s’il y a des erreurs pendant la lecture !
1 t r y { F i l e I n p u t S t r e a m i n = new F i l e I n p u t S t r e a m (
2 new F i l e ( f i l e n a m e ) ) ;
3 . . . // LECTURE
4 i n . c l o s e ( ) ;
5 }c a t c h( . . . ) { in.close(); }
3
Mais ça ne compile pas !
1 FileInputStream in = null;
2 t r y { i n = new F i l e I n p u t S t r e a m (new F i l e ( f i l e n a m e ) ) ;
3 . . . // LECTURE
4 i n . c l o s e ( ) ;
5 }c a t c h( . . . ) { i n . c l o s e ( ) ; }
4
Plus élégant: lignes 4-5 ⇒ finally{in.close()}
Les petits pièges... La fermeture des fichiers
5
La solution précédente ne marche pas encore !
1 F i l e I n p u t S t r e a m i n = n u l l;
2 t r y { i n = new F i l e I n p u t S t r e a m (new F i l e ( f i l e n a m e ) ) ;
3 . . . // LECTURE
4 }f i n a l l y{ i n . c l o s e ( ) ; }
6
... le close est susceptible de lever une exception si le fichier n’est pas ouvert (NullPointerException) !
1 F i l e I n p u t S t r e a m i n = n u l l;
2 F i l e f = new F i l e (" x a n a d u . t x t ") ;
3 t r y {
4 i n = new F i l e I n p u t S t r e a m ( f ) ; // o u v e r t u r e du f i c h i e r
5 // Throws : F i l e N o t F o u n d E x c e p t i o n : => t r y / c a t c h
6
7 // OPERATIONS DE LECTURE
8
9 }
10 } f i n a l l y { // On e s t s u r de p a s s e r p a r l a
11 i f ( i n != n u l l) { // v e r i f i e r que l e f i c h i e r e s t o u v e r t
12 i n . c l o s e ( ) ;
13 }
14 }
2i002 – Flux 8/39
Les petits pièges... La fermeture des fichiers
5
La solution précédente ne marche pas encore !
1 F i l e I n p u t S t r e a m i n = n u l l;
2 t r y { i n = new F i l e I n p u t S t r e a m (new F i l e ( f i l e n a m e ) ) ;
3 . . . // LECTURE
4 }f i n a l l y{ i n . c l o s e ( ) ; }
6
... le close est susceptible de lever une exception si le fichier n’est pas ouvert (NullPointerException) !
1 F i l e I n p u t S t r e a m i n = n u l l;
2 F i l e f = new F i l e (" x a n a d u . t x t ") ;
3 t r y {
4 i n = new F i l e I n p u t S t r e a m ( f ) ; // o u v e r t u r e du f i c h i e r
5 // Throws : F i l e N o t F o u n d E x c e p t i o n : => t r y / c a t c h
6
7 // OPERATIONS DE LECTURE
8
9 }
10 } f i n a l l y { // On e s t s u r de p a s s e r p a r l a
11 i f ( i n != n u l l) { // v e r i f i e r que l e f i c h i e r e s t o u v e r t
12 i n . c l o s e ( ) ;
13 }
14 }
Lecture de fichiers (byte stream)
public int read() throws IOException
Reads a byte of data from this input stream. This method blocks if no input is yet available.
Returns:
the next byte of data, or -1 if the end of the file is reached.
Throws:
IOException - if an I/O error occurs.
1 w h i l e ( ( c = i n . r e a d ( ) ) != −1) {
2 S y s t e m . o u t . p r i n t ( c ) ;
3 }
4 // s i g n i f i e en f a i t :
5 c = i n . r e a d ( ) ; // l e c t u r e d ’ un o c t e t
6 // s u s c e p t i b l e de l e v e r I O E x c e p t i o n => t r y / c a t c h
7 w h i l e ( c != −1) { // t a n t que f i n de f i c h i e r non a t t e i n t e
8 S y s t e m . o u t . p r i n t ( c ) ; // a f f i c h a g e d a n s l a c o n s o l e
9 c = i n . r e a d ( ) ; // l e c t u r e du c a r a c t e r e s u i v a n t
10 }
2i002 – Flux 9/39
Limites → Nouvelles classes
Des classes supplémentaires enrichissent les FileStream:
Processus de décoration d’objets Fonctions de lecture
1 D a t a I n p u t S t r e a m i s t r e a m = n u l l;
2 t r y {
3 i s t r e a m = new D a t a I n p u t S t r e a m (
4 new F i l e I n p u t S t r e a m (new F i l e (" t o t o . d a t ") ) ) ;
5
6 S y s t e m . o u t . p r i n t l n ( i s t r e a m . r e a d C h a r ( ) ) ;
7 S y s t e m . o u t . p r i n t l n ( i s t r e a m . r e a d D o u b l e ( ) ) ;
8 S y s t e m . o u t . p r i n t l n ( i s t r e a m . r e a d I n t ( ) ) ;
9 S y s t e m . o u t . p r i n t l n ( i s t r e a m . r e a d C h a r ( ) ) ;
10 // p a s de f o n c t i o n s p o u r l e s S t r i n g . . .
11 } f i n a l l y{
12 i f( i s t r e a m != n u l l)
13 i s t r e a m . c l o s e ( ) ;
14 }
... Ces fonctions ont évidemment des fonctions symétriques
pour l’écriture
Ecriture
Ecriture de fichiers (byte stream)
public FileOutputStream(String name) throws FileNotFoundException
Creates an output file stream to write to the file with the specified name.
Parameters:
name - the system-dependent filename
Throws:FileNotFoundException - if the file exists but is a directory rather than a regular file, does not exist but cannot be created, or cannot be opened for any other reason
La fonction est proche de celle d’ouverture en lecture... Avec une option supplémentaire: ajouter des choses dans un fichier...
public FileOutputStream(String name, boolean
append) throws FileNotFoundException
Ecriture de fichiers
Exemple d’utilisation (Oracle Java Tutorials) :
1 F i l e I n p u t S t r e a m i n = n u l l;
2 F i l e O u t p u t S t r e a m o u t = n u l l;
3 4 t r y {
5 i n = new F i l e I n p u t S t r e a m (" x a n a d u . t x t ") ;
6 o u t = new F i l e O u t p u t S t r e a m (" o u t a g a i n . t x t ") ;
7 i n t c = i n . r e a d ( ) ;
8
9 w h i l e ( c != −1) {
10 o u t . w r i t e ( c ) ;
11 c = i n . r e a d ( ) ;
12 }
13 } f i n a l l y {
14 i f ( i n != n u l l) {
15 i n . c l o s e ( ) ;
16 }
17 i f ( o u t != n u l l) {
18 o u t . c l o s e ( ) ;
19 }
20 }
Que fait ce programme?
2i002 – Flux 12/39
Limites → Nouvelles classes
1 Octet = 1 char (en fonction du codage)... On voudrait lire des choses de plus haut niveaux
Entier/Double = 4 octets String...
Des classes supplémentaires enrichissent les FileStream:
DataInputStream/DataOutputStream
1 // E c r i t u r e d a n s un f i c h i e r d e s t y p e s de b a s e
2 D a t a O u t p u t S t r e a m o s t r e a m = n u l l;
3 t r y {
4 o s t r e a m = new D a t a O u t p u t S t r e a m (
5 new F i l e O u t p u t S t r e a m (
6 new F i l e (" t o t o . d a t ") ) ) ;
7 o s t r e a m . w r i t e C h a r (’ r ’) ;
8 o s t r e a m . w r i t e D o u b l e ( 2 . 5 ) ;
9 o s t r e a m . w r i t e I n t ( 6 ) ;
10 o s t r e a m . w r i t e C h a r s (" t o t o ") ;
11 } f i n a l l y{
12 i f( o s t r e a m != n u l l)
13 o s t r e a m . c l o s e ( ) ;
14 }
Ouverture en écriture...
Par défaut: remplacement des fichiers existants...
Gare aux catastrophes !
Il existe une option pour ajouter des choses dans un fichier sans écraser le contenu:
1 t r y {
2 o s t r e a m = new D a t a O u t p u t S t r e a m (
3 new F i l e O u t p u t S t r e a m (
4 new F i l e (" t o t o . d a t ") , t r u e) ) ;
5 // l e b o o l e a n c o r r e s p o n d a l ’ o p t i o n a p p e n d
6 . . .
2i002 – Flux 14/39
Fichiers ASCII
ASCII or not ASCII...
Dans les opérations précédentes, voici le fichier manipuler (ouvert avec emacs):
^@r@^@^@^@^@^@^@^@^F^@^@^@t^@o^@t^@o
Ce qui n’est pas très convivial...
En fait il y a des avantages et des inconvénients.
2i002 – Flux 15/39
Gestion de l’ASCII
Distinction entre ASCII et données brutes
Il faut distinguer un fichier ASCII d’une donnée brute:
On peut pas lire directement les int/double sauver par la méthode précédente...
On peut tricher:
1 o s t r e a m . w r i t e C h a r s ( ( ( D o u b l e ) 2 . 5 ) . t o S t r i n g ( ) ) ;
⇒ lisible mais perte de précision Problème de lecture des String
Lecture caractère par caractère fastidieuse
Problème des sauts de ligne (codage différent selon le système)
⇒ Choisir en fonction des situations (possibilité de mélanger)
ASCII or not ASCII...
ASCII
Fichiers de Textes Entêtes des fichiers XML, HTML...
Parfois pour quelques chiffres
lorsque la précision n’est pas importante
pour les fichiers excels...
not ASCII
Fichiers de chiffres Volume Précision
2i002 – Flux 17/39
Gestion en lecture de fichier ASCII
Encore une nouvelle classe : BufferedReader...
public String readLine() throws IOException
Reads a line of text. A line is considered to be terminated by any one of a line feed or a carriage return.
Returns:
A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached
Throws:IOException - If an I/O error occurs
1 B u f f e r e d R e a d e r i n = n u l l;
2 t r y {
3 i n = new B u f f e r e d R e a d e r ( new I n p u t S t r e a m R e a d e r (
4 new F i l e I n p u t S t r e a m ( // d e c o r a t i o n s m u l t i p l e s
5 new F i l e (" x a n a d u . t x t ") ) ) ) ;
6
7 S t r i n g b u f = i n . r e a d L i n e ( ) ;
8 w h i l e( b u f != n u l l) {
9 S y s t e m . o u t . p r i n t l n ( b u f ) ;
10 b u f = i n . r e a d L i n e ( ) ;
11 }
12 } . . .
Stratégie de lecture des fichiers ASCII
Une fois la ligne lue, il est nécessaire de la traiter...
Séparer les mots: StringTokenizer
Choix des séparateurs (espace, tabulation, virgule...), accès aux sous-chaines
Conversion en Int, Double...
public static Double valueOf(String s) throws NumberFormatException
public static Double parseDouble(String s) throws NumberFormatException
2i002 – Flux 19/39
Stratégie alternative
Idée
Combiner la lecture de fichier avec un Tokenizer... Ca donne un Scanner
1 S c a n n e r s = n u l l;
2 t r y {
3 s = new S c a n n e r (
4 new B u f f e r e d R e a d e r (
5 new F i l e R e a d e r (" x a n a d u . t x t ") ) ) ;
6
7 w h i l e ( s . h a s N e x t ( ) ) {
8 S y s t e m . o u t . p r i n t l n ( s . n e x t ( ) ) ;
9 }
10 } f i n a l l y {
11 i f ( s != n u l l) {
12 s . c l o s e ( ) ;
13 }
14 }
Par défaut, le séparateur est ", \ s*" mais on peut le changer...
1 s . u s e D e l i m i t e r (" , \ \ s∗") ;
Ecriture de fichiers ASCII
BufferedReader ⇒ BufferedWriter
1 B u f f e r e d W r i t e r w r i t e r =
2 new B u f f e r e d W r i t e r (
3 new F i l e W r i t e r (
4 new F i l e (" m o n F i c h i e r A S C I I . t x t ") ) ) ;
5
6 w r i t e r . w r i t e (" t o t o ") ;
7 w r i t e r . c l o s e ( ) ;
2i002 – Flux 21/39
Fonctions utiles de formatage du texte
JAVA propose des outils de formatage du texte issu directement de la syntaxe C: c’est utile pour faire des affichages tabulés, ou pour améliorer la lisibilité
Syntaxe usuelle (implicite) de conversion Double → String:
1 i n t i = 2 ;
2 S y s t e m . o u t . p r i n t l n (" i ␣=␣ "+ i ) ;
Syntaxe explicite:
1 i n t i = 2 ;
2 S y s t e m . o u t . p r i n t l n (" i ␣=␣ "+(( I n t e g e r ) i ) . t o S t r i n g ( ) ) ;
Formatage (disponible dans la classe String, entre autre):
static String format(String format, Object... args)
Exemples de formatages
1 d o u b l e[ ] t a b = new d o u b l e[ 1 0 ] ;
2 f o r(i n t i =0; i <10; i ++)
3 t a b [ i ] = Math . random ( )∗1 0 0 0 ;
4 f o r(i n t i =0; i <10; i ++)
5 S y s t e m . o u t . p r i n t l n ( t a b [ i ] ) ;
1 3 0 , 7 8 1 4 0 0 2 4 5 3 , 9 2 6 2 4 6 3 2 1 3 , 1 7 5 5 6 6 4 1 8 , 5 6 5 8 7 3 5 9 4 0 , 0 4 5 8 5 2 6 . . .
1 f o r(i n t i =0; i <10; i ++)
2 S y s t e m . o u t . p r i n t l n (
3 S t r i n g . f o r m a t ("%12 f ", t a b [ i ] ) ) ;
1 3 5 7 , 6 0 0 9 6 0 2 8 3 2 , 2 7 7 0 8 6 3 8 9 , 4 2 3 7 0 6 4 1 2 4 , 3 3 5 3 4 9 5 . . .
1 f o r(i n t i =0; i <10; i ++)
2 S y s t e m . o u t . p r i n t l n (
3 S t r i n g . f o r m a t (" %10.3 f ", t a b [ i ] ) ) ;
1 8 7 0 , 7 7 1 2 7 3 5 , 9 5 2 3 4 4 , 7 7 0 4 . . .
1 f o r(i n t i =0; i <10; i ++)
2 S y s t e m . o u t . p r i n t l n (
3 S t r i n g . f o r m a t (" %010.3 f ", t a b [ i ] ) ) ;
1 0 0 0 8 2 5 , 5 7 9 2 0 0 0 6 1 1 , 9 8 7 3 0 0 0 0 1 3 , 9 8 6 4 . . .
Ca marche aussi avec les entiers (%d) et les String (%s)
2i002 – Flux 23/39
Random Access File
Vers les bases de données...
Fichier structuré
Dans certains fichiers, on souhaite stocker des données structurées, par exemple:
des matrices de chiffres,
des fichiers clients avec des colonnes structurées (eg: nom, prénom, ...)
...
En général, on souhaite faire des traitements associés...
Il faut aller assez vite
2i002 – Flux 24/39
Classe RandomAccessFile
Création/Ouverture assez classique
Option "r", "w", "rw"
Fonction de déplacement du curseur dans le fichier Un certain nombre d’outils classique
read/write sur plusieurs type de données (String, double, int, long...)
setLength pour régler la longueur du fichier
Classe RandomAccessFile
Création/Ouverture assez classique
Fonction de déplacement du curseur dans le fichier
en octets, toujours depuis le début du fichier Un certain nombre d’outils classique
read/write sur plusieurs type de données (String, double, int, long...)
setLength pour régler la longueur du fichier
2i002 – Flux 25/39
Classe RandomAccessFile
Création/Ouverture assez classique
Fonction de déplacement du curseur dans le fichier Un certain nombre d’outils classique
read/write sur plusieurs type de données (String, double, int, long...)
setLength pour régler la longueur du fichier Note: dans ce type de fichier, il faut
1
connaitre la longueur des types usuels (int=4 octets, long = 8 octets, double = 4 octets, char = 1 (ou 2) octet, ...)
2
faire la chasse aux structures de taille variable (comme les String)...
String.format("%10s", "toto")
RandomAccessFile: exemple d’écriture
1 i m p o r t j a v a . i o . R a n d o m A c c e s s F i l e ;
2 [ . . . ]
3 S t r i n g fname = " m o n f i c h i e r t e s t . d a t ";
4 F i l e f = new F i l e ( fname ) ;
5 R a n d o m A c c e s s F i l e r a f = new R a n d o m A c c e s s F i l e ( f , " rw ") ;
6
7 r a f . w r i t e C h a r s ( S t r i n g . f o r m a t ("%4s ", " t i t i ") ) ;
8 r a f . w r i t e C h a r s ( S t r i n g . f o r m a t ("%10 s ", " t o t o ") ) ;
9 r a f . w r i t e D o u b l e ( Math . P I ) ;
10 r a f . w r i t e C h a r s ( S t r i n g . f o r m a t ("%10 s ", " t a t a ") ) ;
11 r a f . c l o s e ( ) ;
Fichier produit:
1 t i t i t o t o ! uTD t a t a
2i002 – Flux 26/39
RandomAccessFile: exemple de lecture Fichier produit:
1 t i t i t o t o ! uTD t a t a
1 R a n d o m A c c e s s F i l e r a f 2 = new R a n d o m A c c e s s F i l e ( f , " rw ") ;
2
3 f o r(i n t i =0; i <4; i ++)
4 S y s t e m . o u t . p r i n t ( r a f 2 . r e a d C h a r ( ) ) ;
5 S y s t e m . o u t . p r i n t l n ( ) ; // t i t i
6
7 r a f 2 . s e e k ( 2 8 ) ;
8 S y s t e m . o u t . p r i n t l n ( r a f 2 . r e a d D o u b l e ( ) ) ; // 3 . 1 4 . . .
9
10 r a f 2 . s e e k ( 8 ) ;
11 f o r(i n t i =0; i <10; i ++)
12 S y s t e m . o u t . p r i n t ( r a f 2 . r e a d C h a r ( ) ) ; // t o t o
13 S y s t e m . o u t . p r i n t l n ( ) ;
14
15 r a f 2 . s e e k ( 0 ) ;
16 S y s t e m . o u t . p r i n t l n ( r a f 2 . r e a d L i n e ( ) ) ;
17 // t i t i t o t o ! uTD t a t a
18
19 r a f 2 . c l o s e ( ) ;
Serializable
Interface Serializable
Si un objet implements Serializable, il devient sauvegardable/chargeable automatiquement Exemple avec la classe Vecteur:
1 p u b l i c c l a s s V e c t e u r impleme nts Serializable{
2 p r i v a t e s t a t i c f i n a l l o n g s e r i a l V e r s i o n U I D =
3 −205627875178186436 L ;
4 p r i v a t e d o u b l e x , y ;
5
6 p u b l i c V e c t e u r (d o u b l e x , d o u b l e y ) {
7 s u p e r( ) ;
8 t h i s. x = x ;
9 t h i s. y = y ;
10 }
11
12 ( . . . )
Serializable: sauvegarde/chargement
1 // s a u v e g a r d e 2 t r y{
3 F i l e O u t p u t S t r e a m f o s =
4 new F i l e O u t p u t S t r e a m ( f i l e n a m e ) ; 5 ObjectOutputStream o o s =
6 new O b j e c t O u t p u t S t r e a m ( f o s ) ; 7 o o s .writeObject(new V e c t e u r ( 2 , 2 ) ) ; 8 f o s . c l o s e ( ) ;
9 }c a t c h ( E x c e p t i o n e ) {
10 S y s t e m . o u t . p r i n t l n ( e . t o S t r i n g ( ) ) ; 11 }
1 // c h a r g e m e n t 2 t r y{
3 F i l e I n p u t S t r e a m f i n =
4 new F i l e I n p u t S t r e a m ( f i l e n a m e ) ; 5 ObjectInputStream o o s =
6 new O b j e c t I n p u t S t r e a m ( f i n ) ; 7 V e c t e u r v = ( V e c t e u r ) o o s .readObject(); 8 f i n . c l o s e ( ) ;
9 }c a t c h ( E x c e p t i o n e ) {
10 S y s t e m . o u t . p r i n t l n ( e . t o S t r i n g ( ) ) ; 11 }
on charge des Object → il faut un cast pour avoir ce que vous voulez
problèmes avec les attributs static
Il faut que les attributs soient sérializable (!)
Eliminer un attribut de la sauvegarde: mot clé transient Problème de version très sensible:
serialVersionUID dans les objets
2i002 – Flux 29/39
Limites d’usage
Lors de la sauvegarde, la Serialization enregistre le type exact de l’objet. Le cas suivant pose problème:
1
Sauvegarde d’un objet
2
Modification (même très légère) de la classe
3
Chargement de l’objet précédent: ClassNotFoundException Ajouter serialVersionUID dans les objets
Bilan
Très facile à utiliser
On ne maitrise pas le format de sauvegarde
Interface Externalizable
Utilisable comme Serializable
Externalizable extends Serializable
Un objet Externalizable EST UN Serializable
Maitrise du format de sauvegarde à travers deux fonctions de lecture/écriture dans les flux...
Dans la classe Vecteur
1 p u b l i c c l a s s V e c t e u r impleme nts E x t e r n a l i z a b l e {
2 ( . . . )
3
4 p u b l i c v o i d r e a d E x t e r n a l ( O b j e c t I n p u t i n ) t h r o w s I O E x c e p t i o n ,
5 C l a s s N o t F o u n d E x c e p t i o n {
6 x = i n . r e a d D o u b l e ( ) ;
7 y = i n . r e a d D o u b l e ( ) ;
8 }
9
10 p u b l i c v o i d w r i t e E x t e r n a l ( O b j e c t O u t p u t o u t ) t h r o w s I O E x c e p t i o n {
11 o u t . w r i t e D o u b l e ( x ) ;
12 o u t . w r i t e D o u b l e ( y ) ;
13 }
2i002 – Flux 31/39
Autres flux
Les flux dépassent les fichiers
Lire une String comme un flux avec la classe StringReader
1 S t r i n g s = " b l a b l a b l a . . . ";
2 // i n i t i a l i s a t i o n a p a r t i r d ’ une S t r i n g
3 S t r i n g R e a d e r s r e a d = new S t r i n g R e a d e r ( s ) ;
4 S y s t e m . o u t . p r i n t l n ( s r e a d . r e a d ( ) ) ; // −> 98 ( c o d e de ’ b ’ )
Fonctionnalité très utile pour unifier une chaine de traitements tous les types d’entrées peuvent être des flux, on peut jouer avec l’héritage
2i002 – Flux 32/39
La console est un flux
Entrée console = un flux particulier (System.in)
1 // c r e e r un S c a n n e r , c h o i s i r un d e l i m i t e u r
2 t r y {
3 s = new S c a n n e r (S y s t e m . i n) ;
4 s . u s e D e l i m i t e r (" ␣ ") ;
5 w h i l e ( s . h a s N e x t ( ) ) {
6 S y s t e m . o u t . p r i n t l n ( s . n e x t ( ) ) ;
7 }
8 } f i n a l l y {
9 i f ( s != n u l l) {
10 s . c l o s e ( ) ;
11 }
12 }
NB: les entrées consoles ne sont validées qu’après un retour chariot
1
Tapons: le lapin + RETOUR
2
Après l’espace, rien ne se passe
3
Après le retour, on voit:
1 l e // l a s e p a r a t i o n a e t e p r i s e en compte
2 l a p i n
Outil avancé pour la console
Objet Console
1 C o n s o l e c = S y s t e m . c o n s o l e ( ) ;
2 i f ( c == n u l l) {
3 S y s t e m . e r r . p r i n t l n ("No␣ c o n s o l e . ") ;
4 S y s t e m . e x i t ( 1 ) ;
5 }
6
7 S t r i n g l o g i n = c . r e a d L i n e (" E n t e r ␣ y o u r ␣ l o g i n : ␣ ") ;
8 c h a r [ ] o l d P a s s w o r d = c . r e a d P a s s w o r d (" E n t e r ␣ y o u r ␣ o l d ␣ p a s s w o r d : ␣ ") ;
Notons la forme particulière de la construction de la console Console est en réalité un Singleton (instance unique de l’objet)... Plus de détail en LI314
2i002 – Flux 34/39
Pipe FIFO
Approche tuyau (FIFO), ce qui rentre en premier sort en premier
1 P i p e d R e a d e r r e a d = new P i p e d R e a d e r ( ) ;
2 P i p e d W r i t e r w r i t e = new P i p e d W r i t e r ( r e a d ) ;
3
4 w r i t e . a p p e n d (" t o t o ") ;
5 w r i t e . a p p e n d (" e s t ␣ d a n s ␣ l e ␣ j a r d i n ") ;
6
7 w h i l e( r e a d . r e a d y ( ) )
8 S y s t e m . o u t . p r i n t l n ( (c h a r) r e a d . r e a d ( ) ) ;
9 // c o n v e r s i o n o b l i g a t o i r e , s i n o n c o d e A S C I I
10 w r i t e . c l o s e ( ) ;
11 r e a d . c l o s e ( ) ;
Problème de la lecture caractère à caractère...
Une idée de solution?
Introduire un Scanner sur la source !
1 S c a n n e r s = new S c a n n e r ( r e a d ) ;
2 w h i l e( s . h a s N e x t ( ) )
3 S y s t e m . o u t . p r i n t l n ( s . n e x t ( ) ) ;
Pipe FIFO
Approche tuyau (FIFO), ce qui rentre en premier sort en premier
1 P i p e d R e a d e r r e a d = new P i p e d R e a d e r ( ) ;
2 P i p e d W r i t e r w r i t e = new P i p e d W r i t e r ( r e a d ) ;
3
4 w r i t e . a p p e n d (" t o t o ") ;
5 w r i t e . a p p e n d (" e s t ␣ d a n s ␣ l e ␣ j a r d i n ") ;
6
7 w h i l e( r e a d . r e a d y ( ) )
8 S y s t e m . o u t . p r i n t l n ( (c h a r) r e a d . r e a d ( ) ) ;
9 // c o n v e r s i o n o b l i g a t o i r e , s i n o n c o d e A S C I I
10 w r i t e . c l o s e ( ) ;
11 r e a d . c l o s e ( ) ;
Problème de la lecture caractère à caractère...
Une idée de solution?
Introduire un Scanner sur la source !
1 S c a n n e r s = new S c a n n e r ( r e a d ) ;
2 w h i l e( s . h a s N e x t ( ) )
3 S y s t e m . o u t . p r i n t l n ( s . n e x t ( ) ) ;
2i002 – Flux 35/39
Lecture http sur le web
Lire sur internet est une simple formalité...
Outil pour les URL → flux Ouverture/lecture classique !
1 URL u r l = new URL (" h t t p : / /www . y a h o o . f r ") ; // o u t i l ad ’ hoc
2 B u f f e r e d R e a d e r b f=new B u f f e r e d R e a d e r (
3 new I n p u t S t r e a m R e a d e r (u r l . o p e n S t r e a m ( ), " u t f 8 ") ) ;
4 S t r i n g b u f = b f . r e a d L i n e ( ) ;
5 w h i l e( b u f != n u l l) {
6 b u f = b f . r e a d L i n e ( ) ;
7 S y s t e m . o u t . p r i n t l n ( b u f ) ;
8 }
9 b f . c l o s e ( ) ;
Collecte de données sur le web
On peut mettre les données lues aux formats:
String : utilisation des méthodes pour sélectionner les parties pertinentes XML : bibliothèque DOM
brutes dans un fichier pour des traitements ultérieurs
...
Dialogue entre machine 1/2
Etablir un lien entre machine = Socket Serveur = ServerSocket
Client = Socket simple pour se connecter
Partie serveur
1 S e r v e r S o c k e t s o c k e t s e r v e r ;
2 S o c k e t s o c k e t d u s e r v e u r ;
3 t r y {
4 s o c k e t s e r v e r = new S e r v e r S o c k e t ( 2 0 0 9 ) ; // c r e a t i o n s e r v e u r
5 s o c k e t d u s e r v e u r = s o c k e t s e r v e r . a c c e p t ( ) ; // a t t e n t e + e c o u t e
6 // + a c c e p t a t i o n
7 S y s t e m . o u t . p r i n t l n (" qqn ␣ s ’ e s t ␣ c o n n e c t e ␣ ! ␣ P o s t e ␣ m e s s a g e ␣ : ␣ ") ;
8
9 // r e t o u r au x m e t h o d e s d e j a v u e s !
10 D a t a O u t p u t S t r e a m o u t =
11 new D a t a O u t p u t S t r e a m ( s o c k e t d u s e r v e u r . g e t O u t p u t S t r e a m ( ) ) ;
12 o u t . w r i t e B y t e s (" m e s s a g e ␣ du ␣ s e r v e u r ") ;
13
14 s o c k e t s e r v e r . c l o s e ( ) ;
15 s o c k e t d u s e r v e u r . c l o s e ( ) ;
16 }c a t c h ( I O E x c e p t i o n e ) { e . p r i n t S t a c k T r a c e ( ) ; }
2i002 – Flux 37/39
Dialogue entre machine 2/2
Coté client
1 S o c k e t s o c k e t ;
2 t r y {
3 s o c k e t = new S o c k e t ( I n e t A d d r e s s . g e t L o c a l H o s t ( ) , 2 0 0 9 ) ;
4 B u f f e r e d R e a d e r b f=new B u f f e r e d R e a d e r (
5 new I n p u t S t r e a m R e a d e r ( s o c k e t . g e t I n p u t S t r e a m ( ) ) ) ;
6 S t r i n g b u f = b f . r e a d L i n e ( ) ;
7
8 S y s t e m . o u t . p r i n t l n (" J e ␣ s u i s ␣ l e ␣ c l i e n t ") ;
9 S y s t e m . o u t . p r i n t l n (" J e ␣me␣ s u i s ␣ c o n n e c t e ") ;
10 S y s t e m . o u t . p r i n t l n (" J ’ a i ␣ l u : ") ;
11 S y s t e m . o u t . p r i n t l n ( b u f ) ;
12
13 s o c k e t . c l o s e ( ) ;
14 }c a t c h ( U n k n o w n H o s t E x c e p t i o n e ) {
15 e . p r i n t S t a c k T r a c e ( ) ;
16 }c a t c h ( I O E x c e p t i o n e ) {
17 e . p r i n t S t a c k T r a c e ( ) ;
18 }
Vers les BD, SQL
Connection aux bases de données aisée
1 // l e d r i v e r g e r e l a c o n n e c t i o n ( a MySQL p a r e x e m p l e )
2 C o n n e c t i o n con = D r i v e r M a n a g e r . g e t C o n n e c t i o n (
3 " j d b c : m y D r i v e r : myDatabase ",
4 u s e r n a m e ,
5 p a s s w o r d ) ;
6
7 // i n s t a n c i a t i o n de l a c o n n e c t i o n
8 S t a t e m e n t s t m t = con . c r e a t e S t a t e m e n t ( ) ;
9 // e n v o i d ’ une r e q u e t e
10 R e s u l t S e t r s = s t m t . e x e c u t e Q u e r y ("SELECT␣ a , ␣b , ␣ c ␣FROM␣ T a b l e 1 ") ;
11 // t r a i t e m e n t s e q u e n t i e l d e s r e p o n s e s
12 w h i l e ( r s . n e x t ( ) ) {
13 i n t x = r s . g e t I n t (" a ") ;
14 S t r i n g s = r s . g e t S t r i n g (" b ") ;
15 f l o a t f = r s . g e t F l o a t (" c ") ;
16 }
2i002 – Flux 39/39