Ecrire et lire des objets dans un fichier binaire.

Résolu
cs_LA_Tupac Messages postés 305 Date d'inscription jeudi 29 avril 2004 Statut Membre Dernière intervention 18 janvier 2012 - 16 août 2011 à 20:45
cs_LA_Tupac Messages postés 305 Date d'inscription jeudi 29 avril 2004 Statut Membre Dernière intervention 18 janvier 2012 - 17 août 2011 à 20:31
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

cs_LA_Tupac Messages postés 305 Date d'inscription jeudi 29 avril 2004 Statut Membre Dernière intervention 18 janvier 2012 1
16 août 2011 à 23:02
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
@++
3
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
17 août 2011 à 14:25
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é. -
3
cs_LA_Tupac Messages postés 305 Date d'inscription jeudi 29 avril 2004 Statut Membre Dernière intervention 18 janvier 2012 1
17 août 2011 à 00:15
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.
0
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
17 août 2011 à 10:15
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é. -
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_LA_Tupac Messages postés 305 Date d'inscription jeudi 29 avril 2004 Statut Membre Dernière intervention 18 janvier 2012 1
17 août 2011 à 12:50
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..
0
cs_LA_Tupac Messages postés 305 Date d'inscription jeudi 29 avril 2004 Statut Membre Dernière intervention 18 janvier 2012 1
17 août 2011 à 14:34
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
0
cs_LA_Tupac Messages postés 305 Date d'inscription jeudi 29 avril 2004 Statut Membre Dernière intervention 18 janvier 2012 1
17 août 2011 à 20:31
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
0
Rejoignez-nous