【问题标题】:What's the clue to make stringstream write binary?让 stringstream 写二进制的线索是什么?
【发布时间】:2011-03-16 07:05:24
【问题描述】:

我想要做的是,让类消息序列化和反序列化它的自我。不是进入或来自文件,而是作为字符串或 cstring 进入或来自二进制序列。

消息.h:

class Message
{
private:
    int message_id;
    int sender_id;

    std::string sender_data;

    Message ();

public:

    Message (int id, std::string data);
    virtual ~Message ();

    virtual const char* Serialize ();
    virtual void Deserialize (const char* buf);

    virtual void Print ();
};

Message.cpp:

const char* Message::Serialize ()
{
    char buf[1024];

// This will work somehow. I get the object and then glibc 
// detects double free or corruption, because i write into buf 
// and not into a file.
//    std::ofstream out_stream(buf, std::ios::binary);
//    out_stream.write((char *)this, sizeof(*this));
//    out_stream.close();

//  Why this won't work? I didn't get it.
    std::stringstream out_stream(buf, std::ios::binary);
    out_stream.write((char *)this, sizeof(*this));

    std::string str(buf);

    std::cout << str << std::endl
              << buf << std::endl;

    return str.c_str();
}

void Message::Deserialize (const char* buf)
{
    std::ifstream in_stream(buf, std::ios::binary);
    in_stream.read((char*)this, sizeof(*this));
    in_stream.close();
}

主要:

#include "Message.h"

int main (int argc, int argv[])
{
    Message msg1(12345, "some data");
    Message msg2(12346, "some other data");

    msg1.Print();
    msg2.Print();

    msg2.Deserialize(msg1.Serialize());

    msg1.Print();
    msg2.Print();

    return 0;
}

输出:

消息:0 客户端:12345 数据:一些数据

消息:1 客户:12346 数据:一些其他数据

消息:0 客户端:12345 数据:一些数据

消息:1 客户:12346 数据:一些其他数据

有什么建议吗? 问候梅沙

【问题讨论】:

  • 将 this 转换为 char* 是未定义的行为,如果 Message 恰好是多态的,就会发生坏事。
  • 好吧,您正在使用虚函数......它会生成存储在对象结构开头的虚函数表。

标签: c++ serialization binary stream


【解决方案1】:

通常,您通过序列化对象的所有数据成员来序列化对象。因此这不会按预期工作:

out_stream.write((char *)this, sizeof(*this));

这不会序列化数据动态分配的数据。

如果您有很多序列化/反序列化要做,请查看Boost.Serialization。即使您不想使用它,阅读文档也可以让您很好地了解它是如何完成的。

如果猜对了,您的代码旨在检查序列化是否按预期工作。通过将要序列化的流作为参数传递给序列化方法,会更好地实现这一点:

std::string Message::Serialize(ostream & sink);

此外,您应该将str::string 用于字符串,而不是const char *

【讨论】:

  • 还没有任何检查。请参阅编辑消息的结构非常简单。我只打算从对象流式传输到二进制序列(c 字符串或字符串),反之亦然。你是对的,会有更多的反序列化,最好是传递一个流。
【解决方案2】:

我想要做的是,让 类消息序列化和 反序列化它的自我。不在或来自 一个文件,但在 / 来自一个字符串。

那么你可能应该看看 XML....

【讨论】:

  • xml 很重且很难正确处理,还有其他用于编组字符串的解决方案,尤其是在您不需要存储层次结构或有内存要求的情况下。你也可以提到 json。
  • XML 不限于文件。
  • @Mesha,XML 是一种与文件存储没有隐式关联的数据格式。
  • 我同意,反正我不想用xml。
  • @Alexandre,xml 并不难,可以很好地作为“字符串表示”的数据格式。
猜你喜欢
  • 1970-01-01
  • 2011-11-22
  • 2018-08-19
  • 2019-07-24
  • 1970-01-01
  • 1970-01-01
  • 2011-09-12
  • 1970-01-01
  • 2014-01-02
相关资源
最近更新 更多