Ecrire et lire des objets dans un fichier binaire. [Résolu]

Signaler
Messages postés
305
Date d'inscription
jeudi 29 avril 2004
Statut
Membre
Dernière intervention
18 janvier 2012
-
Messages postés
305
Date d'inscription
jeudi 29 avril 2004
Statut
Membre
Dernière intervention
18 janvier 2012
-
Salut à tous! J'ai bien cherché mais pas trouvé de réponse dans ces forums. En C++ il est possible de sauvegarder l'instance d'une class en la castant en char* (ou byte* c'est pareil).
En code managé, j'ai l'impression que c'est différent... En tout cas StreamWriter.Write() ne fonctionne pas avec un objet en direct
Alors j'ai besoin d'un petit briefing sur le sujet
Merci d'avance.

7 réponses

Messages postés
305
Date d'inscription
jeudi 29 avril 2004
Statut
Membre
Dernière intervention
18 janvier 2012

En fait il suffit d'avoir les mots qui vont bien
Cela s'appelle Sérialisation en C# Et le p'tit tuto EN
Merci quand-même
@++
Messages postés
1860
Date d'inscription
lundi 28 novembre 2005
Statut
Modérateur
Dernière intervention
14 février 2015
44
Prenons un exemple :

Imaginons que le nombre enregistré dans ton fichier soit un ushort de valeur 61455.
Il s'écrit donc en binaire 11110000 00001111 (l'espace est pour différencier les 2 octets (bytes) de ton ushort).
On commence par mettre val à la valeur 0
val : 00000000 00000000
Puis on lit le premier octet de ta donnée : 11110000 (240)
On ajoute cet octet DÉPLACÉ DE 8 BITS à gauche, soit 11110000 00000000, à val.
val : 11110000 00000000
Enfin, on lit le byte (octet) suivant : 00001111 (15)
Et on ajoute cette valeur à val.
val : 11110000 00001111
Donc val fait bien la bonne valeur.

En revanche, une petite erreur s'est glissée dans mon code : je le suis planté dans le cast :
val += (ushort)(tmpByte << 8);
(ushort)tmpByte;


Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
Messages postés
305
Date d'inscription
jeudi 29 avril 2004
Statut
Membre
Dernière intervention
18 janvier 2012

Erf je suis moins optimiste maintenant
Je ne pense pas que ce soit compatible: lors de la lecture du ushort du headersize, le BinaryFormatter.Deserialize() crash et au bout de la pile d'appel j'ai:
System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadSerializationHeaderRecord (Parameters=) in 

Serialisationheader !! il y'a peut être plus qu'un dump mémoire->fichier

je précise la structure du début de fichier:
char[64]|ushort|ushort|....

Voila le bout de code qui crash:
ushort HeaderSize;
Stream stream = File.Open(filename, FileMode.Open);
stream.Seek(64,0); //pas sûr pour le 0
      	BinaryFormatter bFormatter = new BinaryFormatter();
      	HeaderSize = (ushort)bFormatter.Deserialize(stream);//Crash!

Merci.
Messages postés
1860
Date d'inscription
lundi 28 novembre 2005
Statut
Modérateur
Dernière intervention
14 février 2015
44
Salut

La sérialisation sur une classe fait bien plus qu'un dump mémoire. En effet, le principe de la sérialisation, c'est d'obtenir des données indépendantes de l'emplacement mémoire.
Pour cela, il est obligé de récupérer toutes les références de manière récursive afin de les intégrer à la structure sérialisée.

En revanche, dans le code que tu donnes, ce n'est pas la sérialisation que tu dois utiliser.
En gros, la sérialisation, tu ne dois pas te poser de question sur la structure de ton fichier, car le framework sérialise "à sa guise" ta/tes classe(s).
En gros, c'est vraiment :
jeSerialiseDansMonFichier(monObjet);

et
monObjet = (maClasse)jeDeserialseDepuisMonFichier();

Il ne faut pas chercher plus loin dans l'utilisation.

Si tu veux lire ton ushort, il vaut mieux le faire manuellement (pas testé, mais ça devrait marcher) :
Stream stream = File.Open(filename, FileMode.Open);
stream.Seek(64, SeekOrigin.Begin);
ushort val = 0;
int tmpByte = stream.ReadByte();
val += ((byte)tmpByte) << 8; // On décale de 8 bits vers la gauche
tmpByte = stream.ReadByte();
val += (byte)tmpByte;
stream.Close();


Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
Messages postés
305
Date d'inscription
jeudi 29 avril 2004
Statut
Membre
Dernière intervention
18 janvier 2012

Ok merci c'est bien ce que je pensai...
J'ai essayé ton bout de code mais je vois pas en quoi l'ajout des deux bytes donnerai le nombre sur 16bits...
En tout cas il y'a un soucis de cast int->ushort à la 5ème ligne que je résous en changeant le type de val et en mode débug je n'arrive pas a évaluer val.... le résultat n'est pas bon c'est sur..
Messages postés
305
Date d'inscription
jeudi 29 avril 2004
Statut
Membre
Dernière intervention
18 janvier 2012

Ok une simple erreur de syntaxe donc. Merci je comprend mieux. Je test ça après le taf et je te tiens au jus.
Merci encore
Messages postés
305
Date d'inscription
jeudi 29 avril 2004
Statut
Membre
Dernière intervention
18 janvier 2012

Ok j'ai compris et c'est pas banal
en fait les données de mon fichier sont écrites à l'envers . le ushort 4336 par ex, vaut 10F0h et il est écrit F010h !! Je n'ai aucune idée du pourquoi mais pour info, l'écriture en cpp des données en question se fait par un simple
ofstream.write((char*)monshort, sizeof(short);

Si un guru du cpp peut nous expliquer ça, je serai curieux d'écouter ses explications...
J'ai passé 1 heure a décortiquer ma base en hexa pour découvrir ça et maintenant je dois faire de même pour mes class dumpées à l'envers !!
Bon j'aime bien me faire plaindre mais au boulot !
et merci à toi surtout