310 likes | 411 Views
Sérialisation des objets. flux. 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. clavier, fichier, réseau. source. programme. Flot d'entrée. soit du programme vers une cible externe.
E N D
flux Qu'est-ce qu'un flot? stream Un objetcapable de transférer une suite d'octets • soit d'une source externe vers le programme clavier,fichier,réseau ... source programme Flot d'entrée • soit du programme vers une cible externe écran,fichier,réseau,imprimante ... programme cible Flot de sortie
La jungle des flots ( 60 classes) Package java.io aussi java.util.zip • Flots binaires Information transmise telle quelleoctet par octet • Flots de texte Information subit une transformation("formatage") pour passer au formattexte de la machine hôte
programme fichier Flot de sortie Exemple : écrire des caractères dans un fichier • par un flot binaire Car UNICODEsur 2 octets ces 2 octets • Flots de texte Car code localsur 1 octet Car UNICODEsur 2 octets cet octet Car LF UNIXCar CR et LF MS-DOS '\n'
Flots binaires OutputStream InputStream Manipulent des octets ou tableaux d'octets Attention, entêtes des méthodes trompeuses public abstract intread() throws IOException 1 octet stocké dans un int (0..255) ou -1
Flots binaires utilisés OutputStream octets InputStream DataOutputStream DataInputStream Manipulent des types primitifs + String FileOutputStream FileInputStream Permettent d'associer un flot binaire à un fichier
On "branche" donc des flots sur des flots Exemple : écrire dans un fichier programme fichier DataOuptutStream FileOutputStream int,float,char,.. String DataOutputStream fs = new DataOuputStream (new FileOuputStream("essai.b"));
Flots de texte Writer Reader abstraites Manipulent des caractères (UNICODE) InputStreamWriter InputStreamReader FileReader FileWriter Permettent d'associer un flot de texte à un fichier
En pratique on utilise Pour lire : BufferedReader méthode readLine() Pour écrire : BufferedWriter méthodes write (String) newLine() PrintWriter méthodes print println écrire tous les types primitifs + String Qu'on branche sur des flots de plus bas niveau
Et les objets? Les flots vus auparavant permettent de manipuler des : valeurs de type primitif tableaux de caractères chaînes de caractères (String) Les Objets? Il faut les décomposer. Comment?
"Chaque classe s'occupe des attributs qu'elle définit" (1) Répartition des tâches selon la relation d'héritage sauver(f){écrire a dans f} A a sauver(f){ super.sauver(f) écrire b dans f } B b
(2) Répartition des tâches selon la relation de composition Objet o1Classe C1 Objet oClasse C Objet o2Classe C2 int i Classe C sauver(f){ o1.sauver(f)o2.sauver(f) écrire(i) dans f }
Exemple : application Shogun Les classes FrameJeu fenêtre principalePanneauJoueur panneau de gauchePanneauJeu panneau de droiteJeu gère la partieEchiquier dessine la grilleEnsPieces ensemble de pièces d'un joueurPiece ce qui est commun à toutes les piècesPieceElem pièce "normale"PieceShogun pièce shogun = sauver jeu Sauver une partie en cours ?
Graphe de décomposition d'un objet aquiLeTour jeuJeu pjeuPanneauJeu enspiecesEnsPieces[] ensPieces[O] ensPieces[1] joueur EnsPieces EnsPieces vPiecesVector PieceShogun TObject[] PieceElem
Sérialisation "automatique" Classe java.io.ObjectOutputStream public final void writeObject(Object obj) throws IOException Classe java.io.ObjectInputStream public final ObjectreadObject() throws OptionalDataException, ClassNotFoundException, IOException Ces classes permettent aussi de manipuler des types primitifs
Ces méthodes ne s'appliquent qu'à des objets • sérialisables = dont la classe implémente l'interface Java.io.Serializable (interface "marqueur") • Cette propriété s'hérite • Si on prend le graphe de l'objet : tous les objets du • graphe doivent être sérialisables • (sinon NotSerializableException)
aquiLeTour jeuJeu enspiecesEnsPieces[] Piece ensPieces[O] ensPieces[1] joueur EnsPieces EnsPieces vPiecesVector PieceShogun TObject[] PieceElem Jeu, EnsPieces et Piece doivent implémenterl'interface Serializable
Le menu est géré par des attributs de la fenêtre (objet de la classe FrameJeu) JMenuBar JMenu JMenuItem sauver restaurer
Action associée à sauver : - choix d'un nom de fichier nomFic (utiliser FileDialog) - demander à jeu de se sauvegarder dans le fichier nomFic pjeu.jeu.sauve(nomFic);
Jeu public void sauve (String nomFic) throws IOException { ObjectOutputStream flotS = new ObjectOutputStream (new FileOutputStream(nomFic)); flotS.writeObject(this); flotS.close(); } L'objet jeu
Dans FrameJeu - dans constructeur de FrameJeu : JMenuItemmSauve = new JMenuItem("Sauver"); mRestaure.addActionListener(new ActionListener() { public void actionPerformed (ActionEvent e) { mSauveAction(e);} });
- Ailleurs dans FrameJeu : public void mSauveAction(ActionEvent evt) { … pjeu.jeu.sauve(nomFic); … } Problème : throws IOException
mSauve.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) throws IOException { mSauveAction(e);} }); On n'a pas le droit de faire remonter les exceptionsà actionPerformed (cf. interface ActionListener) Donc obligé de capturer les exceptions avant (dans mSauveAction par exemple)
public void mSauveAction(ActionEvent evt) { … try { pjeu.jeu.sauve(nomFic);} catch (IOException e){ // message sur fenêtre console par ex. // afficher aussi e.getMessage()} }
Action associée à restaurer : - choix d'un nom de fichier nomFic (utiliser FileDialog) - demander à jeu de se restaurer depuis le fichier nomFic Problème : c'est justement l'objet jeu qu'il fautcréer => Une méthode statique dans Jeu qui crée un jeu pjeu.jeu = Jeu.restaure(nomFic);
Jeu public static Jeu restaure(String nomFic) throws IOException, ClassNotFoundException { ObjectInputStream flotE = new ObjectInputStream (new FileInputStream (nomFic)); Object o = flotE.readObject(); Jeu j = (Jeu) o; return j; }
Constructeur de FrameJeu mRestaure.addActionListener (new ActionListener() { public void actionPerformed(ActionEvent e) { mRestaureAction(e);} });
FrameJeu public void mRestaureAction(ActionEvent evt) { … try {pjeu.jeu = Jeu.restaure(nomFic);} catch (Exception e) {….} }
Sérialisation : la conclusion • Avantages • Automatique • Peut gérer des objets complexes Inconvénient Flots binaires : fichiers pas lisibles