Sobes.tech
Junior

En quels types peut-on diviser la sérialisation?

sobes.tech IA

Réponse de l'IA

La sérialisation peut être divisée en les types fondamentaux suivants, en fonction de la façon dont les données sont représentées :

  • Textuelle : Les données sont représentées dans un format lisible, généralement sous forme de chaînes.

    • Avantages : Facilité de débogage, indépendance de l'architecture.
    • Inconvénients : Volume de données accru, nécessité de parsing.
    • Exemples : JSON, XML, YAML.
  • Binaire : Les données sont représentées dans un format brut, binaire.

    • Avantages : Compacité, vitesse élevée de sérialisation/désérialisation.
    • Inconvénients : La lecture des données est difficile sans schéma, problèmes potentiels de compatibilité entre différentes architectures (par exemple, endianness).
    • Exemples : Protocol Buffers, Apache Thrift, Cap'n Proto, MessagePack.

De plus, la sérialisation peut être classée selon la méthode d'application :

  • Manuelle : Le développeur écrit explicitement le code pour convertir les données de l'objet en octets et vice versa.

    • Exemple :
    // Exemple de sérialisation manuelle d'un int
    int data = 12345;
    std::vector<char> buffer;
    buffer.resize(sizeof(int));
    std::memcpy(buffer.data(), &data, sizeof(int));
    
  • Automatique (réflexion/génération de code) : Utilisation de bibliothèques ou d'outils qui effectuent automatiquement la sérialisation/désérialisation en fonction des informations sur la structure des données.

    • Exemple : Utilisation de bibliothèques telles que Boost.Serialization, cereal, RapidJSON (avec des adaptateurs personnalisés), ou des outils de génération de code pour Protocol Buffers.
    // Exemple d'utilisation de boost::serialization
    #include <boost/archive/binary_oarchive.hpp>
    #include <boost/archive/binary_iarchive.hpp>
    #include <fstream>
    #include <iostream>
    
    struct MyData {
        int x;
        double y;
    
        template<class Archive>
        void serialize(Archive & ar, const unsigned int version)
        {
            ar & x;
            ar & y;
        }
    };
    
    void save(const MyData& data, const std::string& filename) {
        std::ofstream ofs(filename);
        boost::archive::binary_oarchive oa(ofs);
        oa << data;
    }
    
    void load(MyData& data, const std::string& filename) {
        std::ifstream ifs(filename);
        boost::archive::binary_iarchive ia(ifs);
        ia >> data;
    }
    

Il est également important de prendre en compte :

  • Schéma vs Sans schéma : Faut-il une définition explicite de la structure des données (schéma) ou le format de données est-il auto-descriptif ?
  • Flux vs Bufferisé : La sérialisation peut-elle se faire au fur et à mesure de la réception des données ou faut-il tout charger en mémoire avant la sérialisation/désérialisation ?