37
Flots et Sérialisation des objets

Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Embed Size (px)

Citation preview

Page 1: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Flots et

Sérialisation des objets

Page 2: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Qu'est-ce qu'un flot? Stream

Un objet capable de transférer une suite d'octets

• soit d'une source externe vers le programme

• soit du programme vers une cible externe

Flot d'entrée (ou de lecture)

Flot de sortie (ou d’écriture)

source programmeclavier,fichier,réseau ...

cible programmeécran,fichier,réseau,imprimante ...

Page 3: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

La jungle des flots ( 60 classes en java 2)

• Flots binaires

Package java.io aussi java.util.zip (…)

Information transmise telle quelleoctet par octet

• Flots de texte

Information subit une transformation("formatage") pour passer du codage UNICODEutilisé en java au format texte de la machine hôteet inversement

Page 4: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

• par un flot binaire

Exemple : écrire des caractères dans un fichier

• par un flot de texte

Flot de sortie

programme fichier

Car UNICODEsur 2 octets

ces 2 octets

Car UNICODEsur 2 octets

Car code localsur 1 octet

cet octet

'\n' Car LF UNIXCar CR et LF MS-DOS

Le fichier obtenu est lisible par un éditeur de texte

Page 5: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Flots binaires

InputStream OutputStream

Manipulent des octets ou tableaux d'octets

Attention, entêtes des méthodes trompeuses

Par exemple, dans InputStream :public abstract int read() throws IOException

lit un seul octet stocké dans un int (0..255) ou -1 si rien lu

Page 6: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Flots binaires utilisés

InputStream OutputStream

Manipulent des octets

DataInputStream DataOutputStream

Lire et écrire des types primitifs + String

FileInputStreamPermettent d'associer un flot binaire à un fichiermais ne possèdent que des méthodes (de lecture ou d’écriture) de bas niveau

FileOutputStream

abstraites

Page 7: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

On "branche" donc des flots sur des flots

Exemple : écrire dans un fichier

DataOuptutStream

programme fichier

int,float,char,… String

FileOutputStream

DataOutputStream fs = new DataOuputStream(new FileOuputStream(“test.bb"));

fs.writeChars(“la chaine a ecrire”);………fs.close();

Page 8: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Flots de texte

Reader Writer

Manipulent des caractères(UNICODE format hôte)

abstraites

InputStreamReader InputStreamWriter

FileReader

Permettent d'associer un flot de texte à un fichier

FileWriter

Page 9: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

En pratique on utilise

Pour lire :

BufferedReader méthode readLine()

Pour écrire :

BufferedWriter méthodes write (String) newLine()

PrintWriter méthodes print println

pour écrire tous les types primitifs + String

Qu'on branche sur des flots de plus bas niveau

Page 10: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

BufferedReader fc = new BufferedReader(new InputStreamReader(System.in));

String chaineLue = fc.readline();

int i = Integer.parseInt(chaineLue);

Depuis la version 5, on a aussi la classe Scanner :

Scanner sc = new Scanner(System.in);

int i = sc.nextInt();

Exemple : lire un entier tapé au clavier

Page 11: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

BufferedReader ff = new BufferedReader (new FileReader ("essai.txt"));

// Lecture du fichier "essai.txt"String s = ff.readLine();

/* readLine() retourne :la ligne lue jusqu'au retour chariot

(lu mais non retourné) donc une chaîne vide si la ligne n’a qu'un RC la valeur null s'il n'y a rien à lire */

while (s!= null){ System.out.println(s);//affichage

console s = ff.readLine();}

ff.close();

Exemple : lire un fichier texte et l’afficher (console)

Page 12: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

BufferedReader fc = new BufferedReader (new InputStreamReader (System.in));

BufferedWriter ff = new BufferedWriter (new FileWriter ("essai.txt"));

System.out.println("Entrez des lignes

(Return pour terminer)");String s = fc.readLine();while (s.length() != 0){ ff.write(s); // TQ pas chaîne vide ff.newLine();

s = fc.readLine();}ff.close();

Exemple : créer un fichier texte par lecture au clavier

Page 13: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Et les objets?

Les flots que nous venons de voir permettent de manipuler des :

variables ou valeurs de type primitif

tableaux de caractères

chaînes de caractères (String)

Les Objets autres que des String?

Page 14: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Lecture/écriture d’objets

• Méthode « artisanale »

Ecriture : décomposer l’objet à sauvegarder jusqu’à obtenir des données de type primitif ou des String

Lecture : reconstruire un objet (de la bonne classe !)à partir des données de type primitif ou des String lues

• Méthode automatique : sérialisation

(Attention : sauvegarde au format binaire uniquement)

Page 15: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Principe : décomposition d’un objet jusqu’à arriver à des données de type primitif ou String

Objet od’une classe C

Objet o1 d’une classe C1

Objet o2 d’une classe C2

int i

Quelque part, un objet flot a été créé

sauver(flot){ o1.sauver(flot) o2.sauver(flot) flot.écrire(i)}

Classe C

Page 16: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Exemple : Minidraw (éditeur graphique)

Fenêtre fenêtre principalePanneau panneau CollectionFigures collection de figures

qui encapsule un ArrayList

ArrayList<Figure> encapsule un tableau de figures

Figure classe racine des figuresRect une sorte de figureRectPlein d’autres sortes de figuresOvale … OvalePlein…

Les classes

Sauver un dessin ? = sauver la collectionde Figures

Page 17: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Graphe de décomposition de la collection de figures

monDessinCollectionFigures

tabArrayList<Figure>

TFigure[] Rect

Ovale

RectPlein

compteur int

x int y int …………On décompose l’objet jusqu’à arriver à

des données de type primitif ou des String

Page 18: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Le graphe de décomposition peut être plus complexe qu'une arborescence

Pourquoi on dit « sérialisation »

Page 19: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Que faudrait-il sauvegarder pour pouvoir reconstituer le dessin ?

compteur "Rect" x y Lh Lv colTrait "Oval" x y Lh Lv colTrait"RectPlein" x y Lh Lv colTrait colFond

monDessinCollectionFigures

tabArrayList<Figure>

TFigure[] Rect

Ovale

RectPlein

compteur int

x int y int …………

Page 20: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Où seraient implémentées les méthodes ?

- Quelque part , créer un flot associé à un fichier Méthode sauve(flot) dans CollectionFigures

- écrire le nombre de figures (compteur)- appeler une méthode « sauve » pour chaque figure

Méthode sauve(flot) d’une classe de figure :

- écrit le « type » - écrit les attributs définis dans cette classe- appelle la méthode super.sauve(flot) pour les attributs dont elle hérite

compteur "Rect" x y Lh Lv colTrait "Oval" x y Lh Lv colTrait"RectPlein" x y Lh Lv colTrait colFond

Page 21: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

– Sérialisation –Méthode "automatique"

public final void writeObject(Object obj)

throws IOException

Classe java.io.ObjectOutputStream

public final Object readObject() throws OptionalDataException, ClassNotFoundException, IOException

Classe java.io.ObjectInputStream

• Ces classes permettent aussi de manipuler des types primitifs (méthodes writeInt, readInt, …)

•Les tableaux sont des objets

Page 22: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

• Ces méthodes ne s'appliquent qu'à des objets sérialisables

= dont la classe implémente l'interface java.io.Serializable (interface "marqueur")

• La propriété d’être sérialisable s'hérite : si une classe implémente une interface, ses sous-classes aussi

• Prenons le graphe de décomposition de l'objet : tous les objets du graphe doivent être sérialisables

(sinon NotSerializableException)

Page 23: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Quelles classes doivent implémenter l’interface Serializable ?

CollectionFigures ArrayList (c’est le cas) Figure

monDessinCollectionFigures

tabArrayList<Figure>

TFigure[] Rect

Ovale

RectPlein

compteur int

x int y int …………

Page 24: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Exemple de la sauvegarde

et de la restauration

d’une collection de figures

en détails

Page 25: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

La barre de menu est ajoutée à la fenêtre JMenuBar Jmenu JMenuItem

A l’entrée de menu “sauver” on associe un écouteur d’une classe anonyme, dont la méthode actionPerformed appelle la méthode sauve() de la fenêtre

Rappel : la sélection d’une entrée de menu se gère comme une action sur bouton

Même principe pour “restaurer” méthode restaure() de la fenêtre

Page 26: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Méthode sauve() de la fenêtre

- choix d'un nom de fichier Fic (par boîte de dialogue)- demande à panneau de sauver le dessin dans le fichier de nom Fic

panneau.sauveDessin(Fic);

Méthode restaure() de la fenêtre

- choix d'un nom de fichier Fic (par boîte de dialogue)- demande à panneau de restaurer le dessin depuis le fichier de nomFic

panneau.restaureDessin(Fic);

Page 27: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

public void sauveDessin (File Fic) {

ObjectOutputStream flotS = new ObjectOutputStream

(new FileOutputStream (Fic));

flotS.writeObject(monDessin);

flotS.close();

}

Classe Panneau Gère des infos sur un fichier

Que faire de l’exception (IOException) susceptible d’être générée par writeObject ?On la retransmet à la méthode appelante (donc méthode sauve de la fenêtre)

throws IOException

Page 28: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Revenons à la classe Fenêtre :

public void sauve()

{ ………………panneau.sauveDessin(Fic);

}

Problème : “throws IOException” de sauveDessin

De toutes façons, actionPerformed ne peut pas déclarer “throws IOException” (car l’interface ActionListener nel’a pas prévu et qu’une redéfinition de méthodene peut ajouter des exceptions)

La méthode “sauve” ne peut ignorer cette exception :- la retransmet à la méthode appelante (actionPerformed) - ou la capture et la traite

Page 29: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Donc on capture et traite l’exception si elle survient :

public void sauve()

{ ………………try // surveiller ce bloc d’instructions

{ panneau.sauveDessin(Fic); }catch (IOException e) // capturer l’exception si elle survient

{ // traiter le problème JOptionPane.showMessageDialog (null, “Erreur de sauvegarde”);

}

}

Page 30: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Implémentons maintenant la méthode restaure() de la fenêtre

- choix d'un nom de fichier Fic (par boîte de dialogue)- demande à panneau de restaurer le dessin depuis le fichier de nomFic

panneau.restaureDessin(Fic);

public void restaureDessin (File Fic) { ObjectInputStream flotE = new ObjectInputStream

(new FileInputStream (Fic));

Utiliser flotE.readObject()pour recréer l’objet monDessin

}

Classe Panneau

Page 31: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

public void restaureDessin (File Fic) throws IOException,ClassNotFoundException

{ ObjectInputStream flotE = new ObjectInputStream

(new FileInputStream (Fic));

Object o = FlotE.readObject(); monDessin = (CollectionFigures) o;

flotE.close();

// demander l’appel de paintComponent repaint();

}

Classe Panneau

Page 32: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Dans la classe Fenêtre, il faut traiter les exceptions pouvant être générées par restaureDessin:

public void restaure()

{ ……………… panneau.restaureDessin(Fic); }

{ ………………try // surveiller ce bloc d’instructions

{ panneau. restaureDessin(Fic); }catch (Exception e) // capturer tout type d’exception !!

{ // on fait le service minimum JOptionPane.showMessageDialog (null, “Erreur de restauration”);

}}

Page 33: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Résumé

Entrée de menu« Sauver » Écouteur.actionPerformed(…)

sauve()

Choix Ficpanneau.sauveDessin(Fic)

sauveDessin(Fic)

writeObject(monDessin)

PANNEAU

FENETRE

Suite d’appels similaire pour « Restaurer »

Page 34: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Choisir un fichier

File Fic = null;JFileChooser chooser = new JFileChooser();

int rep = chooser.showSaveDialog(this);/* affiche une boîte de dialogue permettant de choisir un fichier existant ou nouveau */if (rep == JFileChooser.APPROVE_OPTION) Fic = chooser.getSelectedFile();

Pour la sauvegarde

Pour la restauration : chooser.showOpenDialog

/* affiche une boîte de dialogue permettant de choisir un fichier existant */

Indiquer le parent de la boîteou null

Page 35: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Conclusion sur la sérialisation

Avantages

• Automatique

• Permet de gérer facilement des objets complexes

Inconvénient

Flots binaires : fichiers pas lisibles

[Suite : application au TP Same]

Page 36: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

Quels fichiers dans le TP « Same » ?

• Sauvegarde et restauration d’une configuration initiale

- que sauvegarder ? La matrice de pions ? mécanisme de sérialisation Une matrice de couleurs (ou d’entiers) ? méthode « artisanale » Juste le « seed » (pour générer la même série d’entiers) sauvegarder un entier (de type long) utiliser System.currentTimeMillis() pour générer un seed

- n’autoriser la sauvegarde qu’en début de partie voir dans JMenuItem : public void setEnabled(boolean b)

Page 37: Flots et Sérialisation des objets. Qu'est-ce qu'un flot? Stream Un objet capable de transférer une suite d'octets soit d'une source externe vers le programme

• Sauvegarde et affichage des x meilleurs scores

- on gère des couples (nom, score) sans doute commode de créer une classe ScoreItem et de gérer un tableau de ScoreItem

- fichier binaire plutôt que texte ? (éviterait une modification sauvage des scores) le mécanisme de sérialisation est alors utilisable

- à la fin d’une partie, mise à jour éventuelle du fichier des scores

- afficher en permanence les x meilleurs scores ?