sérialisation des objets. qu'est-ce qu'un flot? flux stream un objet capable de...
TRANSCRIPT
Sérialisation des objets
Qu'est-ce qu'un flot? flux
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
source programme
Flot d'entrée
cible programme
Flot de sortie
clavier,fichier,réseau ...
écran,fichier,réseau,imprimante ...
La jungle des flots ( 60 classes)
• 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 au formattexte de la machine hôte
• par un flot binaire
Exemple : écrire des caractères dans un fichier
• Flots 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
Flots binaires
InputStream OutputStream
Manipulent des octets ou tableaux d'octets
Attention, entêtes des méthodes trompeuses
public abstract int read() throws IOException
1 octet stocké dans un int (0..255) ou -1
Flots binaires utilisés
InputStream OutputStream octets
DataInputStream DataOutputStream
Manipulent des types primitifs + String
FileInputStream
Permettent d'associer un flot binaire à un fichier
FileOutputStream
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("essai.b"));
Flots de texte
Reader Writer
Manipulent des caractères (UNICODE)
abstraites
InputStreamReader InputStreamWriter
FileReader
Permettent d'associer un flot de texte à un fichier
FileWriter
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 typesprimitifs + 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
A
B
a
b
sauver(f){écrire a dans f}
sauver(f){ super.sauver(f) écrire b dans f }
(2) Répartition des tâches selon la relation de composition
Objet oClasse C
Objet o1Classe C1
Objet o2Classe C2
int i
sauver(f){ o1.sauver(f) o2.sauver(f) écrire(i) dans f }
Classe C
Exemple : application Shogun
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
Les classes
Sauver une partie en cours ? = sauver jeu
Graphe de décomposition d'un objet
pjeuPanneauJeu
jeuJeu
aquiLeTour
enspiecesEnsPieces[]
ensPieces[O] ensPieces[1]
EnsPieces EnsPieces
vPiecesVector
joueur
TObject[]
PieceShogun
PieceElem
Sérialisation "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
• 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)
jeuJeu
aquiLeTour
enspiecesEnsPieces[]
ensPieces[O] ensPieces[1]
EnsPieces EnsPiecesvPiecesVector
joueur
TObject[]
PieceShogun
PieceElem
Piece
Jeu, EnsPieces et Piece doivent implémenterl'interface Serializable
Le graphe peut être plus complexequ'un arborescence
Le menu est géré par des attributs de la fenêtre (objet de la classe FrameJeu)
JMenuBarJMenuJMenuItem 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);
public void sauve (String nomFic) throws IOException
{
ObjectOutputStream flotS = new ObjectOutputStream
(new FileOutputStream (nomFic));
flotS.writeObject(this);
flotS.close();
}
L'objet jeu
Jeu
Dans FrameJeu
- dans constructeur de FrameJeu :
JMenuItem mSauve = 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
On n'a pas le droit de faire remonter les exceptionsà actionPerformed (cf. interface ActionListener)
mSauve.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) throws IOException
{ mSauveAction(e);}
});
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);
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;
}
Jeu
mRestaure.addActionListener (new ActionListener()
{ public void actionPerformed(ActionEvent e)
{ mRestaureAction(e);}
});
Constructeur de FrameJeu
public void mRestaureAction(ActionEvent evt)
{ …
try
{pjeu.jeu = Jeu.restaure(nomFic);}
catch (Exception e)
{….}
}
FrameJeu
Sérialisation : la conclusion
Avantages
• Automatique
• Peut gérer des objets complexes
Inconvénient
Flots binaires : fichiers pas lisibles