La sérialisation (et son petit frère casse pied, la déserialisation)

akd Message lu Posté le 18 Août 2008 à 11:59 Bulle
Avatar de akd
Membre Confirmé

Messages : 319
GCPoints : 75439
Bonjour,

Déjà pour ceux qui ne connaissent pas ces termes:

La sérialisation, consiste à enregistrer dans un certain format, des données présentes en mémoire (donc volatiles) sur un support physique (donc persistant).

La déserialisation est le concept inverse qui à partir de données stockées dans un fichier physique permet de recréer les entités en mémoire.

A l'époque antique où j'ai appris à programmer en C++ (IUT), on nous avait fait travailler sur ces principes sans en dire le nom. Bien entendu, l'un des principales "soucis" de C++ c'est qu'à ma connaissance il ne possède pas d'aide pour sérialiser/désérialiser les données, il faut donc écrire toutes les routines à la main.

En C# et en Java, il existe des mécanismes tout fait pour permettre ces opérations. (Par exemple ceux qui ont eu affaire aux Enterprise Java Bean -EJB- s'en sont déjà servis / dans mon cas sans le savoir avant d'aller tripatouiller le code généré automatiquement par JDeveloper).

L'une des principales utilités dans notre domaine qu'est la programmation orientée Jeux Vidéo de ces principes de sérialisation/désérialisation est la génération de sauvegarde et l'aide au chargement/déchargement de scripts.

En C#, j'ai jusqu'à présent étudié deux grandes familles permettant la sérialisation/désérialisation des données.

XMLSerializer, permet de générer des fichiers XML (pratique pour sauvegarder des scripts).

Serializer permet de générer des fichiers binaires (pratique pour les sauvegardes des parties).

Maintenant tout ces prérequis posés, voici mon problème actuel (sérialisation binaire):
- je veux sauvegarder différentes entités issues de classes différentes dans un même fichier (jusqu'ici pas de soucis)
- à la désérialisation comment est ce que je retrouve mes différents types d'entité pour les remettre dans des classes du bon type?

(J'ai une petite idée, mais j'aime vous lancer des défis) :happy:
Mod Message lu Posté le 18 Août 2008 à 12:11 Bulle
Avatar de Mod
Webmaster

Messages : 4954
GCPoints : 2100823
Je n'ai jamais approfondi ce domaine, pas de chance ^^'. La seule fois où j'ai tâté de la sérialisation, c'est en C, avec les unions... Pas le top, je pense.

Mais tel que je l'ai appris, la sérialisation se définit plutôt comme la subdivision de données en entités de taille inférieure. Que l'on peut ensuite stocker ou envoyer par le réseau.
akd Message lu Posté le 18 Août 2008 à 13:58 Bulle
Avatar de akd
Membre Confirmé

Messages : 319
GCPoints : 75439
En fait pour être plus précise, même si personnellement je m'en sers pour les processus de sauvegarde/restauration, c'est effectivement aussi utilisé pour le transfert de données via le réseau.

Ce qui est tout à fait compatible puisqu'on ouvre un flux de données pour stocker les infos (vers un fichier sur disque pour moi, vers un ordinateur distant dans ton cas).

On peut effectivement définir les attributs qui seront sérialisés et ceux qui ne le seront pas; ce qui permet donc de réduire la quantité de données transmises.
Dernière édition le 18 Août 2008 à 14:00
SEB Message lu Posté le 18 Août 2008 à 15:05 Bulle
Avatar de SEB
Membre Evolué

Messages : 554
GCPoints : 103313

Citation :


Maintenant tout ces prérequis posés, voici mon problème actuel (sérialisation binaire):
- je veux sauvegarder différentes entités issues de classes différentes dans un même fichier (jusqu'ici pas de soucis)
- à la désérialisation comment est ce que je retrouve mes différents types d'entité pour les remettre dans des classes du bon type?



Je pense que la solution est dans la question... pour connaitre le type ^^ il faut trouver un moyen de le sauvegarder aussi et la... plusieurs méthodes sont possibles donc libre à ton imagination !!

Mais l'idée la plus simple (d'apres moi) :
identifieur de type
données.....
identifieur de type
données...

etc... ce qui fait que la lecture se fait de la manière suivante :
Lecture de type
Creation de l'objet correspondant
remplissagee de l'objet avec les données...
Lecture de type
Création de l'objet correspondant
remplissage avec les données...

Voila apres il y a d'autres méthodes je pense mais celle ci est la plus simple à comprendre

++
Seb
NextGine : 3D games engine
Nombre de lignes actuel : 77683
akd Message lu Posté le 18 Août 2008 à 15:18 Bulle
Avatar de akd
Membre Confirmé

Messages : 319
GCPoints : 75439
Le problème est justement au niveau de l'identifiant du type de données.

En effet en C# les exemples que j'ai vu travaillent en indiquant clairement le type de données avant d'aller la désérialiser du flux.

Le hic dans mon cas c'est que je stocke l'ensemble des données dans un même fichier binaire sans prendre en compte le type.

J'ai donc pensé à une classe intermédiaire qui aurait deux composants:
un champ object
un champ string

dans l'object, je stockerais la classe à sérialiser (boxing en C#) et dans string son type.
Il faudrait donc tout simplement sérialiser ces composants et les déserialiser derrière.

Il y a plusieurs soucis avec cette méthode:
- il est nécessaire de préparer au préalable les données qui vont être boxées (en remplaçant les données qu'on ne veut pas sérialiser par du null, de même pour les références à des entités qui n'existeront plus)
- l'utilisation des mots clés [Serializable] et [non serialized] sur les classes à sérialiser deviennent totalement inutile puisque c'est des object qu'on va sérialiser (le système ne peut donc pas savoir ce qui devait être conservé) <- on perd quasiment l'intérêt de cette fonctionnalité.

Par contre à la déserialisation on a à peine plus de travail que d'habitude (il suffit juste de reconvertir les object dans leur type de données en plus de la désérialisation- unboxing-).

la grande question est : arriverais-je à récupérer mes données sans perte à la désérialisation? (je n'ai pas encore fait d'essais en réel et j'ai peur qu'il considère le moindre champ string comme étant mon "type_of").

Un autre idée aurait été de se servir d'XML et du fait qu'il existe des balises ouvrantes et fermantes (donc des délimiteurs "explicites") et de stocker dans chacune de ses balises le contenu d'un "fichier binaire" composés d'objets du même type.
Dernière édition le 18 Août 2008 à 15:26
SEB Message lu Posté le 19 Août 2008 à 09:01 Bulle
Avatar de SEB
Membre Evolué

Messages : 554
GCPoints : 103313
Ce que j'aurais fait personellement à première vue c'est une cmasse abstraite : Sérialisable qui fait que si une classe en hérite elle peut etre sérialisée via une surcharge de méthode sinon non.

En suite pour la désérialisation j'aurais créé une Factory qui renvoie une sorte de racine sur la structure sauvegardée et reconstituée enfin.

Voila sinon tu peu toujours peut-etre jetter un coup d'oeil ici :
http://blog.developpez.com/nico-pyright?title=c_et_c_cli_serialisation_et_deserialisat
">
http://blog.developpez.com/nico-pyright?title=c_et_c_cli_serialisation_et_deserialisat


++
Seb
NextGine : 3D games engine
Nombre de lignes actuel : 77683
gouessej Message lu Posté le 23 Sep 2008 à 09:25 Bulle
Membre Avancé

Messages : 337
GCPoints : 64624

Citation :

En C#, j'ai jusqu'à présent étudié deux grandes familles permettant la sérialisation/désérialisation des données.

XMLSerializer, permet de générer des fichiers XML (pratique pour sauvegarder des scripts).

Serializer permet de générer des fichiers binaires (pratique pour les sauvegardes des parties).


C'est vrai pour Java aussi, il n'y a pas que les Java beans, il y a aussi les classes XMLEncoder/XMLDecoder.
akd Message lu Posté le 23 Sep 2008 à 10:25 Bulle
Avatar de akd
Membre Confirmé

Messages : 319
GCPoints : 75439
C'est interessant que tu en fasses mention, je vais justement avoir besoin d'y jeter un oeil pour un doc d'étude que je fais pour mon boulot.

Comme quoi :proud:
gouessej Message lu Posté le 28 Nov 2008 à 13:41 Bulle
Membre Avancé

Messages : 337
GCPoints : 64624
Moi aussi j'en ai eu besoin pour le boulot mais j'étais le seul à savoir m'en servir alors j'ai dû me démerder tout seul :confused:
Répondre
GameCorp - Site d'apprentissage et d'entraide à la création de jeux vidéo.
XHTML Valid 1.1 - Page générée en 0.038 secondes