Sériaisation Phiippe GENOUD UJF Novembre 2010 1 Sériaisation Objet en mémoire Sériaiser un objet consiste à construire une représentation compacte de ceui-ci et à envoyer sur un fux de sortie Objet sériaisé vitesse 280 vitessemax 320 Sériaisation réseau 10101000110 00101010101 heap fichier JVM Phiippe GENOUD UJF Novembre 2010 2 1
Désériaisation Objet en mémoire Désériaiser un objet créer un objet en mémoire à partir d une représentation compacte de ceui-ci obtenue sur un fux d entrée Objet sériaisé vitesse 280 vitessemax 320 Désériaisation réseau 10101000110 00101010101 heap fichier JVM Phiippe GENOUD UJF Novembre 2010 3 Présentation générae Sériaisation binaire Permet de rendre des objets persistants en écrivant es données présentes en mémoire vers un fux de données binaires introduction dans e JDK 1.1 d'un mécanisme de sériaisation permet de sériaiser es objets de manière transparente et indépendante du système d'expoitation. s'appuie sur es fux d'entrée sortie (java.io) Permet d'identifier es casses sériaisabes Object OutputStream InputStream <interface> Seriaizabe Impémente e mécanisme de sériaisation ObjectOutputStream Impémente e mécanisme de désériaisation ObjectInputStream Phiippe GENOUD UJF Novembre 2010 4 2
Casses ObjectOutputStream et ObjectInputStream ObjectOutputStream représente "un fux objet" qui permet de sériaiser un objet grâce à a méthode writeobject(). ObjectInputStream représente "un fux objet" qui permet de désériaiser un objet grâce à a méthode Object readobject(). Person Dog name Kiki age 12 name Jean firstname Dupont age 24 pet Méthode writeobject() de ObjectOutputStream 10011010110101 Objet sériaisé Méthode readobject() de ObjectInputStream Cast vers type Person Person name Jean firstname Dupont age 24 pet Dog name Kiki age 12 Phiippe GENOUD UJF Novembre 2010 5 Sériaisation Qu advient-i des objets référencés par objet qui est sériaisé? int vitesse 280 int vitessemax 320? objet Moteur Moteur moteur Roue[] roues objet Voiture objet tabeau de roues Seriaisation Phiippe GENOUD UJF Novembre 2010 6 3
Sériaisation Quand un objet est sériaisé tous es objets qu i référence au travers de variabe d instance sont automatiquement sériaisés. De même que e sont tous objets référencés par ces objets Et ainsi de suite objet Jante int vitesse 280 int vitessemax 320 String marque "Ferrari" objet String objet Roue objet Pneu objet Jante Roue[] roues objet Voiture Seriaisation objet tabeau de Roue objet Pneu objet Jante objet Pneu Le graphe d objets est sériaisé dans son entier. objet Jante objet Pneu Phiippe GENOUD UJF Novembre 2010 7 Interface Seriaizabe Pour qu'un objet puisse être sériaisé sa casse doit impémenter 'interface Seriaizabe ou hériter d'une casse ee-même sériaisabe. pubic interface Seriaizabe { Interface qui ne contient ni attributs ni méthode. Interface de marquage (tag interface) La sériaisation d'un objet consiste à écrire ses attributs sur un fux de sortie binaire. Tout attribut est sériaisé si : I est de type primitif (int, char, booean,.) ou est une référence dont e type est un type sériaisabe (dans ce cas 'objet référencé est sériaisé) I n'est pas décaré static I n'est pas décaré transient I n'est pas hérité d'une casse mère sauf si cee-ci est ee-même sériaisabe Phiippe GENOUD UJF Novembre 2010 8 4
Exempe import java.io.seriaizabe; import java.uti.arraylist; import java.uti.iterator; import java.uti.list; pubic cass Reaisateur impements Seriaizabe { La casse doit être marquée comme étant sériaisabe pubic String getnom () { return nom; private String nom; private String prenom; private List<Fim> fims; pubic Reaisateur (String nom, String prenom) { this.nom = nom; this.prenom = nom; fims = new ArrayList<Fim>(); pubic String getprenom () { return prenom; pubic Iterator<Fim> fims () { return fims.iterator(); pubic void addfim (Fim f) { fims.add(f); Phiippe GENOUD UJF Novembre 2010 9 Exempe import java.io.seriaizabe; pubic cass Fim impements Seriaizabe { private String titre; private int annéesortie; private Reaisateur réaisateur; La casse doit être aussi marquée comme étant sériaisabe pubic Fim (String t, int a, Reaisateur r) { titre = t; annéesortie = a; réaisateur = r; réaisateur.addfim(this); pubic int getannéesortie () { return annéesortie; pubic Reaisateur getreaisateur () { return réaisateur; pubic String gettitre () { return titre; Phiippe GENOUD UJF Novembre 2010 10 5
Exempe Pour écrire a sériaisation d'un Reaisateur dans un fichier on utiise : Un ObjectOutputStream qui sériaise 'objet et produit un fux binaire Un FieOutputStream qui redirige ce fux vers un fichier Un BufferedOutputStream pour améiorer es performances Reaisateur ObjectOutPutStream 10011010110101 BufferedOutputStream FieOutputStream FieOutputStream fos = new FieOutputStream("monReaisateur.ser") BufferedOutputStream bos = new BufferedOutputStream(fos); Est-ce que quequ'un a vu ObjectOutputStream oos = new ObjectOutputStream(fos); e bug? Phiippe GENOUD UJF Novembre 2010 11 Exempe Reaisateur ObjectOutPutStream 10011010110101 BufferedOutputStream FieOutputStream FieOutputStream fos = new FieOutputStream("monReaisateur.ser") BufferedOutputStream bos = new BufferedOutputStream(fos); ObjectOutputStream oos = new ObjectOutputStream(fos); Par a suite seu 'ObjectOutputStream sera utiisé on préférera donc 'écriture bos ObjectOutputStream oos = new ObjectOutputStream( new BufferedOutputStream( FieOutputStream("monReaisateur.ser") ) ); Phiippe GENOUD UJF Novembre 2010 12 6
Exempe import java.io.bufferedoutputstream; import java.io.fieoutputstream; import java.io.objectoutputstream; pubic cass PersistUtiities { pubic static void savereaisateurtoseriafie(string fiename, Reaisateur r) { Création d'un ObjectOutputStream dont e fux de sortie est redirigé vers e fichier de nom fiename ObjectOutputStream oos = new ObjectOutputStream( new BufferedOutputStream(new FieOutputStream(fieName))); oos.writeobject(r); Sériaisation de 'objet Reaisateur oos.cose(); Fermeture du fux de sortie Phiippe GENOUD UJF Novembre 2010 13 Exempe import java.io.bufferedoutputstream; import java.io.fieoutputstream; import java.io.ioexception import java.io.objectoutputstream; pubic cass PersistUtiities { pubic static void savereaisateurtoseriafie(string fiename, Reaisateur r) throws IOException { ObjectOutputStream oos = new ObjectOutputStream( new BufferedOutputStream(new FieOutputStream(fieName))); try { oos.writeobject(r); finay { oos.cose(); Pour GARANTIR a fermeture du fux de sortie Phiippe GENOUD UJF Novembre 2010 14 7
Exempe La récupération d'un objet à partir du fichier de sériaisation est simiaire pubic static Reaisateur getreaisateurtoseriafie(string fiename) throws IOException, CassNotFoundException { Création d'un ObjectInputStream qui it ses données dans e fichier de nom fiename Reaisateur r = nu; ObjectInputStream ois = new ObjectInputStream( new BufferedInputStream(new FieInputStream(fieName))); try { Object obj = ois.readobject(); if (obj instanceof Reaisateur) r = (Reaisateur) obj; finay { ois.cose(); return r; Fermeture du fux de sortie désériaisation du premier objet contenu dans e fichier Phiippe GENOUD UJF Novembre 2010 15 Exempe pubic static void main(string[] args) { test.ser Reaisateur r1 = new Reaisateur("Kubrick", "Staney"); Fim f1 = new Fim("2001 'Odyssée de 'espace", 1968, r1); Fim f2 = new Fim("The Shining", 1980, r1); Fim f3 = new Fim("Dr. Foamour", 1963, r1); try { System.out.printn("r1 " + r1); PersistUtiities.saveReaisateurToSeriaFie("test.ser", r1); Reaisateur r2 = PersistUtiities.getReaisateurToSeriaFie("test.ser"); System.out.printn("r2 " + r2); System.out.printn("r1 = r2 " + (r1 == r2)); catch (Exception ex) { ex.printstacktrace(); r1 Reaisateur : Staney Kubrick 2001 'Odyssée de 'espace 1968 The Shining 1980 Dr. Foamour 1963 r2 Reaisateur : Staney Kubrick 2001 'Odyssée de 'espace 1968 The Shining 1980 Dr. Foamour 1963 r1 = r2 fase Phiippe GENOUD UJF Novembre 2010 16 8
seriaversionuid??? e seriaversionuid permet d'affecter un numéro de version à a casse. utiisé ors de a désériaisation afin de s'assurer que es versions des casses Java sont concordantes. une InvaidCassException evée si seriaversionuid différents. Si e seriaversionuid n'est pas expicitement définit e JRE en cacu un par défaut, mais a javadoc dit : It is strongy recommended that a seriaizabe casses expicity decare seriaversionuid vaues, since the defaut seriaversionuid computation is highy sensitive to cass detais that may vary depending on compier impementations, and can thus resut in unexpected seriaversionuid conficts during deseriaization, causing deseriaization to fai. Phiippe GENOUD UJF Novembre 2010 17 seriaversionuid??? Définir e champ seriaversionuid dans e code de a casse Théoriquement cette vaeur devrait être changé orsqu'un champ non transient est ajouté ou supprimé de a casse Phiippe GENOUD UJF Novembre 2010 18 9
Seriaisation Java vs Seriaisation XML Sériaisation Binaire (Java) Pour Utiise des casses Java standards Performances rapides Format de sériaisation compact Contre Format imité au monde Java Non isibe par 'homme Nécessite de modifier es casses Sériaisation XML Pour Format standard Lisibe par 'homme Peut être utiisé par des programmes non Java Pas besoin de modifier es casses Contre Nécessite une ibrairie tiers (thirdparty) Fichiers non compressés Pus ent pour des gros objets Phiippe GENOUD UJF Novembre 2010 19 Ecriture dans un fichier XML Sauvegarder un objet dans un fichier XML Convertir 'objet en une chaîne (String) XML converttoxml() Sauvegarder a chaîne dans un fichier texte savestringtofie() Charger un objet depuis un fichier XML monobjet.xm Lire a chaîne XML depuis e fichier texte getstringfromfie() Convertir a chaîne XML en un Objet convertfromxml() Phiippe GENOUD UJF Novembre 2010 20 10
XStream Projet Open source pour sériaisation d'objets Java en XML Enregistrer a distribution de XStream (ici xstream- 1.3.jar) 1 2 Phiippe GENOUD UJF Novembre 2010 21 XStream Ajouter xstream aux ibrairies du projet (ici sous NetBeans 6.5) 4 3 Phiippe GENOUD UJF Novembre 2010 22 11
Exempe sériaisation XML Ajout des méthodes de conversion et ecture écriture dans a casse PersistUtiities Conversion d'un objet Reaisateur en une chaîne XML Création d'un objet Reaisateur à partir chaîne XML XMLString peut correspondre à un objet de n'importe que type. La méthode fromxml retourne donc Object Phiippe GENOUD UJF Novembre 2010 23 Exempe sériaisation XML Sauvegarde d'une chaîne dans un fichier texte Lecture d'une chaîne depuis un fichier texte Ajouter des chaînes à un StringBuffer est beaucoup pus rapide que de concaténer des objets String Bouce whie : 1. Lire dans a String s a igne suivante 2. Si s n'est as nu, 'ajouter à sb 3. Repéter jusqu'à a fin du fichier (s est aors nu) readline() retire es caractères de retour à a igne. On es rajoute à a chaîne Phiippe GENOUD UJF Novembre 2010 24 12
Exempe sériaisation XML test.xm Phiippe GENOUD UJF Novembre 2010 25 Exempe sériaisation XML Le fichier test.xm Nom compet de a casse de 'objet Attribut de 'objet Position reative de 'objet référencé L'utiisation des noms compets pour es casses et de chemins reatifs pour es références peuvent nuire à a isibiité du fichier XML Phiippe GENOUD UJF Novembre 2010 26 13
Exempe sériaisation XML Possibiité de configurer a sortie XML. Conversion d'un objet Reaisateur en une chaîne XML Définition d'un aias qui sera utiisé à a pace du nom compet de a casse de 'objet Création d'un objet Reaisateur à partir chaîne XML Les références seront représentées par un ID au ieu d'utiiser des chemins reatifs Lors de a ecture i faut définir es mêmes règes que ors de 'écriture Phiippe GENOUD UJF Novembre 2010 27 Exempe sériaisation XML Fichier test.xm Phiippe GENOUD UJF Novembre 2010 28 14
Références La sériaisation binaire en Java, Yann D'ISANTO http://ydisanto.deveoppez.com/tutories/j2se/seriaisation/partie1/ seriaversionuid mythes et égendes http://www.touieur-express.fr/2008/01/26/seriaversionuid-mytheset-egendes/ XStream http://xstream.codehaus.org/ XStream two minutes tutoria http://xstream.codehaus.org/tutoria.htm Ecipse and Java: Introducing Persistence http://ecipsetutoria.sourceforge.net/persistence.htm Phiippe GENOUD UJF Novembre 2010 29 Phiippe GENOUD UJF Novembre 2010 30 15