Sobes.tech
Junior

Em que tipos se pode dividir a serialização?

sobes.tech IA

Resposta da IA

A serialização pode ser dividida nos seguintes tipos fundamentais, com base na forma como os dados são representados:

  • Textual: Os dados são apresentados num formato legível, geralmente na forma de strings.

    • Vantagens: Facilidade de depuração, independência da arquitetura.
    • Desvantagens: Maior volume de dados, necessidade de parsing.
    • Exemplos: JSON, XML, YAML.
  • Binária: Os dados são apresentados num formato bruto, binário.

    • Vantagens: Compactação, alta velocidade de serialização/deserialização.
    • Desvantagens: Leitura de dados dificultada sem esquema, possíveis problemas de compatibilidade entre diferentes arquiteturas (por exemplo, endianness).
    • Exemplos: Protocol Buffers, Apache Thrift, Cap'n Proto, MessagePack.

Além disso, a serialização pode ser classificada de acordo com o método de aplicação:

  • Manual: O programador escreve explicitamente o código para converter os dados do objeto em bytes e vice-versa.

    • Exemplo:
    // Exemplo de serialização manual de int
    int data = 12345;
    std::vector<char> buffer;
    buffer.resize(sizeof(int));
    std::memcpy(buffer.data(), &data, sizeof(int));
    
  • Automática (reflexão/geração de código): São utilizadas bibliotecas ou ferramentas que realizam automaticamente a serialização/deserialização com base na informação da estrutura de dados.

    • Exemplo: Uso de bibliotecas como Boost.Serialization, cereal, RapidJSON (com adaptadores personalizados), ou ferramentas de geração de código para Protocol Buffers.
    // Exemplo de uso do 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;
    }
    

Também é importante considerar:

  • Esquema vs Sem esquema: É necessário uma definição explícita da estrutura de dados (esquema) ou o formato de dados é auto-descritivo?
  • Fluxo vs Bufferizado: Pode a serialização ocorrer à medida que os dados são recebidos ou é necessário carregar todo o volume de dados na memória antes de serializar/deserializar.