IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

Serialisation portable d'obj connu


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2005
    Messages : 87
    Par défaut Serialisation portable d'obj connu
    Bonjour,

    Je dois dans un cadre scolaire développer une classe capable de sérialiser une classe connue afin d'enregistrer tout ses occurences dans un seul et même fichier binaire.
    J'inisite que je connais à quel type de classe je vais devoir sauvegarder via read/write de iostream.

    Avant de commencer à coder cette classe, voici les questions que je me pose:

    Comment peut-on éditer une des occurences du fichier de sauvegarde binaire sans devoir réécrire tout le fichier (bah oui, j'ai des char* = taille nonf-fixe> débordement sur un autre obj déja sérializé)
    La seule solution que j'ai: recharger tout les occurences dans un vecteur (template home-made), éditer celle que je veux et tout réécrire.

    Comment faire en sorte que les fichiers sérialisés fonctions sur les archtectures SPARC & i386 sans traitments des fichiers au changement de plateforme. Je crois que la représentation des entiers et d'autres choses peuvent poser problème. Existe t'il des "parades" à ce genre de problème?

    Ce travail est dans le but scolaire afin d'obtenir une matrise sur ostream & la sérialisation. Je ne peut ni utiliser boost ni la stl.

    Quelqu'un aurait-il une idée pour m'aider à résoudre les deux problèmes évoqués ci-dessus.

    PS: si mon titre n'est pas assez "parlant" ne pas hésiter à le modifier ou déplacer le topic

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Il faut savoir que, l'un dans l'autre, un fichier binaire a toutes les chances de ne jamais être compatible entre architectures différentes...

    Que ce soit parce qu'un caractère risque de ne pas utiliser le même nombre de bits, parce qu'il y a un problème de boutisme, ou... les raisons sont nombreuses pour en arriver à ce point.

    La solution pourrait passer par un encodage de type "TCP/IP", par lequel tu déciderais une bonne fois pour toute d'une taille et d'un boutisme particulier pour maintenir les informations dans ton fichier de sauvegarde.

    A ce moment là, ce sera cependant le programme qui devra être adapté à l'architecture (avec une éventuelle conversion little endian<-->big endian si l'architecture sur laquelle le fichier est lu n'est pas celle sur laquelle le fichier est créé), éventuellement par directives préprocesseurs, si tu ne veux pas avoir à maintenir deux codes différents.

    Pour ce qui est de la conversion big<-->little endian, tu peux te tourner vers les fonction htons et ntohs.

    D'un autre coté, si je peux comprendre un prof qui demande de ne pas utiliser boost (quoi que, j'attendrai de connaitre ses motivations avant de le laisser faire sans réagir), je ne comprendrai jamais un prof qui refuse que tu utilise la STL, surtout si c'est pour essayer de faire des programmes portables.

    Ceci dit, l'avantage d'un fichier binaire, c'est que tu sais normalement précisément la taille que pourra prendre une structure donnée.

    Si même tu te retrouve avec une chaine de caractères, le mieux est de faire un nombre de caractères correspondant à la taille maximale de celle-ci.

    Cela occasionnera sans doute une "perte d'espace", dans le sens où, si tu prévois 50 caractères pour ta chaine et que le mot tient en 10, tu te retrouvera avec 40 caractères '\0', mais cela te permettra d'effectuer un parcours indexé sur les structures enregistrées

    Il te sera donc éventuellement possible (pour la lecture, non pour l'écriture) de te dire que, si tu veux accéder au Neme élément du fichier, tu dois partir du début, passer l'éventuelle en-tete que tu aurais fournies (dont, entre autres, le nombre d'éléments qu'il contient, voire, des informations concernant la structure), puis aller à l'index correspondant à (N-1)*taille de la structure sauvegardée.

    Pour l'écriture, tu n'aura pas le choix: un fichier est toujours "gravé dans le marbre": si tu veux apporter la moindre modification à l'intérieur du fichier (l'ajout en fin de fichier est possible), il faudra... casser la dalle et le recommencer
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2005
    Messages : 87
    Par défaut
    M.E.R.CI pour la réponse.

    Jvé m'attaquer dès ce soir au problème de l'architecture et voir htons et ntohs.
    Saurais tu me me dire comment détecter si l'os est solaris ou si l'architecture est sparc ?
    Ici une réponse interessante. Dois-je continuer à chercher ?

    Coté fichier, je vais essayer de faire une segmentation assez large pour que tout mes objets "rentrent" dans chaque segment (barbare un jour,.... toujours).

    L'interet de ne pas utiliser la stl ? Laisser les petits élèves vivre sans string... et donc faire des setters à la noix pour y mettre des new & strcpy. Aussi pour nous apprendre à créer nous même un conteneur template valable de A à Z pour nos types créés avec nos petits doigts. Si on donne tout aux élèves le copier coller est trop vite fait et la démarche intellectuelle est absente. Mais j'aime bien, cela nous fait prendre conscience des mécanismes qui sont déja mit en place pour nous.

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Haknaton Voir le message
    M.E.R.CI pour la réponse.

    Jvé m'attaquer dès ce soir au problème de l'architecture et voir htons et ntohs.
    Saurais tu me me dire comment détecter si l'os est solaris ou si l'architecture est sparc ? (snip)
    • Pour ce qui est des os, tu trouvera ton bonheur ==>ici<==
    • Pour ce qui est des compilateurs, tu trouvera une liste bien complete ==> ici <==
    • Enfin, pour ce qui en est des architectures, c'est la page d'à coté: elle se trouve ==> ici <==
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2005
    Messages : 87
    Par défaut
    J'ai trouvé une perle ! Comment faire toutes les transformations de type sans prise de tête direction une FAQ ?

    Et maintenant je planche sur comment faire une classe qui va se charger de sérialiser & faire les read/write du fichier.
    Je suis en train de me casser la tête pour avoir une classe template, que je peux hériter et qui devra gerer l'enregistrement de plusieurs objets dans en fichier en ce souciant de réécrire sur l'objet si il existait déja.

    J'ai pris l'option de segmenter mon fichier à la taille de mon plus "gros" objet que je peux obtenir. J'ai calculé la taille du segment à l'aide de la taille des buffers que j'utilise pour saisir mes char* + marge d'erreur ... pas très compliqué au final.

    Mais je ne vois pas comment créer une classe qui pourra serialiser mes objets sans les connaitres. En fait je ne sais pas trop comment orienter la chose. Si je dois faire une classe qui s'occupe du boulot ou si je doit faire une classe dont peuvent hériter mes objets.

    Vous avez des idées pour un étudier qui doit réinventer la roue ?
    Une petite idée de pattern ou un truc du genre?

    Merci déja à tous pour les réponses que vous m'avez fournit.

  6. #6
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Regarder boost::serialization peut donner des idées, même s'il est difficile de tout faire dans un programme d'exemple.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  7. #7
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par Haknaton Voir le message
    Comment faire en sorte que les fichiers sérialisés fonctions sur les archtectures SPARC & i386 sans traitments des fichiers au changement de plateforme. Je crois que la représentation des entiers et d'autres choses peuvent poser problème. Existe t'il des "parades" à ce genre de problème?
    Oui partiellement.
    1- Décider du format qu'aura chaque type de donnée dans le fichier sérialisé (dans quel ordre les bytes seront écrits...), sans se préoccuper trop de la manière dont c'est représenté sur une machine particulière
    2- N'écrire dans le fichier que des unsigned char ou tableaux d'unsigned char, jamais de types plus évolués

    Ex : Sauver un int i sur 4 octets :
    unsigned char buffer[4];
    buffer[0] = i;
    buffer[1] = i >> 8;
    buffer[2] = i >> 16;
    buffer[3] = i >> 24;
    Puis on sauve buffer.


    Pourquoi partiellement seulement ?

    - Parce qu'il sera difficile/impossible de trouver un tel format neutre pour les flottants si les deux machines ne respectent pas la même norme de représentation (mais ça devrait être très rare).

    - Parce que si la structure contient des types qui n'ont pas le même intervalle de valeur possible d'une machine à l'autre (ex un int qui serait 32 bits d'un côté, 64 bits de l'autre), je ne vois pas ce qu'on peut faire.

    Citation Envoyé par koala01 Voir le message
    D'un autre coté, si je peux comprendre un prof qui demande de ne pas utiliser boost (quoi que, j'attendrai de connaitre ses motivations avant de le laisser faire sans réagir), je ne comprendrai jamais un prof qui refuse que tu utilise la STL, surtout si c'est pour essayer de faire des programmes portables.
    Le seul intérêt que je peux voir, c'est susciter l'intérêt et l'envie par l'interdiction... De façon à ce que, quand elle est levée, les élèves se ruent sur le fruit défendu...
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  8. #8
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2005
    Messages : 87
    Par défaut
    Et les fonction de conversion htonl/ntohl proposées par koala01 ne résolvent pas mon problème ? Il me semble d'ailleur qu'elle font leur job (si necessaire) suivant l'achitecture sans détection préable de celle-ci
    Il faut absolument passer par des char pour avoir une compatibilité sur nos unix i386 et les jolis solaris sparc de mon école ?

    Tout les types doivent être dissolus en char ? Sinon quels sont ceux qui échapent à cette transformation ? Qui des chaines de caractères (sachant qu'elles sont Très nombreuses dans mes objets *à mort le char *, avec string ça aurait été pire :/ string -> char[] -> version portable)

    Je me demande au final si je suis pas en train de me compliquer vachement la tache pour ne pas me casser la tête a avoir 2 lots de fichier de data raw.


    Pour répondre encore à la question de l'enseignement: si on ne comprend pas les bases, inutile de voir plus loin. Laisser des élèves ne sachant pas ce que c'est une classe utiliser la STL ou Boost ça serait de la folie pur. Mais après 6 mois du dur labeur nous auront droit de l'utiliser. Chouette

  9. #9
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par Haknaton Voir le message
    Et les fonction de conversion htonl/ntohl proposées par koala01 ne résolvent pas mon problème ?
    Elle le font probablement, la méthode que je propose a les avantages suivants :
    - Elle marche pour d'autres types que long et short
    - Elle ne demande pas l'utilisation d'une bibliothèque non standard (qui plus est dédiée au réseau, et non à la sérialisation...) (et ce qui me semblait t'être interdit)
    - Elle permet d'écrire un fichier à un format spécifié, si on doit s'adapter à un format existant, au lieu d'imposer le format "réseau".


    Citation Envoyé par Haknaton Voir le message
    Il me semble d'ailleur qu'elle font leur job (si necessaire) suivant l'achitecture sans détection préable de celle-ci
    Il n'y a pas non plus de détection d'architecture dans ma méthode, pour peu que les architectures soient suffisamment semblables (ce qui est nécessaire aussi avec hton*). Il y en a même moins, car la localisation du header décrivant les hton* n'étant pas standard, tu vas devoir faire du code platform spécifique pour l'inclure
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  10. #10
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2005
    Messages : 87
    Par défaut
    Je veux pas faire le casse pied .... mais ....

    Si le nombre d'octet utilisés pour un type change d'une plateforme à l'autre ? on fait comment ?

    Il faudra que je me renseigne car je crois que c'est le cas sous les sparc de l'école.

    Prochaine lecture à l'aube sous les néons du labo ....

Discussions similaires

  1. Comment faire un Timer de fonction PORTABLE ?
    Par dieuP1guin dans le forum C
    Réponses: 3
    Dernier message: 04/07/2003, 10h44
  2. Delphi7 winxp pro renvoyer un TLabel connu par nom
    Par regis1_1 dans le forum Composants VCL
    Réponses: 3
    Dernier message: 18/06/2003, 11h09
  3. Code Portable
    Par D[r]eadLock dans le forum C
    Réponses: 9
    Dernier message: 14/09/2002, 13h44
  4. [Migratation] Application portable, indépendant du SGDB
    Par benouille dans le forum Décisions SGBD
    Réponses: 6
    Dernier message: 28/08/2002, 13h51
  5. Choix d'un EDI pour la 3D (Open GL, Portable)
    Par Riko dans le forum OpenGL
    Réponses: 6
    Dernier message: 01/08/2002, 12h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo