【问题标题】:Need library for binary stream serialization, C++需要二进制流序列化库,C++
【发布时间】:2012-12-13 07:40:58
【问题描述】:

我正在寻找的类似于 RakNet 中内置的序列化库(我不能在我当前的项目中使用它)。我需要能够在本地将二进制流保存/加载为自定义格式,并通过网络发送它们。网络部分已经解决了,但我真的不想编写自己的方法来将我所有不同类型的数据序列化为二进制文件,尤其是因为如果没有任何压缩方法,效率会很低。

这是一些类似于 RakNet 比特流工作方式的伪代码,这与我正在寻找的内容一致:

class Foo
{
public:
    void Foo::save(BitStream& out)
    {
        out->write(m_someInt);
        out->write(m_someBool);
        m_someBar.save(out);

        // Alternative syntax
        out->write<int>(m_someInt);

        // Also, you can define custom serialization for custom types so you can do this...
        out->write<Bar>(m_someBar);

        // Or this...
        out->write(m_someBar);     
    }

    void Foo::load(BitStream& in)
    {
        in->read(m_someInt);
        in->read(m_someBool);
        in->read(m_someBar);
    }

private:
    int m_someInt;
    bool m_someBool;
    Bar m_someBar;
};

是否有任何免费的 C++ 库允许这样的事情?我基本上只是想要一些东西将我的数据打包成二进制文件,然后将其压缩以进行序列化,然后将其解压缩回二进制文件,以便我可以反馈到我的数据中。

编辑,添加更多信息:
不幸的是,Google Protocol Buffers 或 Boost Serialization 都不能满足我的需要。两者都希望序列化对象成员,我需要简单地序列化数据。例如,假设我有一个std::vector&lt;Person&gt;,类Person 有一个std::string 的名称和其他数据,但我只想序列化和反序列化它们的名称。使用 Google 协议缓冲区,它希望我将 Person 对象作为一个整体提供给它以进行序列化。但是,我可以通过 Boost 序列化来实现这一点,但是如果我有另一个需要序列化整个 Person 的场景,则无法做到这一点,您要么必须序列化所有序列化,要么不序列化。基本上我需要相当多的灵活性来制作二进制流,但我认为合适,我只想要一个库来帮助我管理从流中读取和写入二进制数据,以及压缩/解压缩它。

【问题讨论】:

    标签: c++ serialization deserialization


    【解决方案1】:
    1. Google Protocol Buffers
    2. Boost serialization

    更新

    查看更新后的问题,我认为编写一个完全符合要求的小型自定义库可能是最简单的。我有一个类似的,它只有几百行代码(没有压缩)。为这种代码编写单元测试非常容易,因此从一开始就可靠。

    为了序列化自定义类型,我有一个 Persistent 基类,它具有保存和加载方法:

    class Storage {
    public:
      void writeInt( int i );
      void writeString( string s );
      int readInt();
      string readString();
    };
    
    class Persistent {
    public:
      virtual void save( Storage & storage ) = 0;
      virtual void load( Storage & storage ) = 0;
    };
    
    class Person : public Persistent {
    private:
      int height;
      string name;
    public:
      void save( Storage & storage ) {
        storage.writeInt( height );
        storage.writeString( name );
      }
    
      void load( Storage & storage ) {
        storage.readInt( height );
        storage.readString( name );
      }
    };
    

    然后有一个简单的层,它在保存时存储一些类型信息,并在加载时使用工厂创建新对象。

    这可以通过使用 C++ 的流(我不太喜欢,因此使用 Storage 类)来进一步简化。或者复制 Boost 使用 & 运算符将加载和保存合并到一个方法中的方法。

    【讨论】:

    • 我有一些我应该提到的特殊需求。我已将这些详细信息添加到我的原始帖子中。据我所知,这些需求使我无法使用您提到的两个库中的任何一个(它们是我在此处发布之前研究的前两个)。
    • 回应您更新的答案:我考虑过编写自己的读/写方法,我可能最终会走那条路,但我认为我自己写是不合理的任何短时间内的压缩/解压缩算法。我想我可以为此使用图书馆。我会继续为您的答案投票,如果我在第二天左右没有得到更好的答案,我会将这个标记为答案。感谢您的帮助。
    • @NicFoster 我确信使用现有的库很容易添加压缩。例如,Boost 有一个用于 iostream 的 gzip 过滤器。
    猜你喜欢
    • 2012-09-12
    • 2016-07-27
    • 2017-10-17
    • 2017-10-18
    • 1970-01-01
    • 1970-01-01
    • 2010-12-17
    • 2015-09-17
    • 2016-02-21
    相关资源
    最近更新 更多