什么样的分隔符用于序列化?

时间:2013-07-16 15:40:09

标签: c++ string serialization

我正在构建一个ostringstream。

我正在将int写入此流。

我在2个数字之间使用stream<<" ";。 我将此流转换为字符串,UDP将其发送。

在接收方,我使用这些函数将字符串拆分为“”空格字符的单个数字。

std::vector<std::string> split(const std::string &s, char delim) {
    std::vector<std::string> elems;
    split(s, delim, elems);
    return elems;
}


std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
    std::stringstream ss(s);
    std::string item;
    while (std::getline(ss, item, delim)) {
        elems.push_back(item);
    }
    return elems;
}

现在我想写二进制数据,所以
使用写入功能我正在写二进制数据,例如 来自此处的数据结构(http://robot.kaist.ac.kr/haptics/chai3d-2.0.0_Doc/resources/html/structc_matrix3d.html

void  insert_into_stream(std::ostream& stream, const cMatrix3d rot)
{
    cVector3d column; 
    unsigned int byteCounter = 0;
    int length = sizeof(double)*3;
    char insert_buffer[sizeof(double)*9];

    column  = rot.getCol0();
    memcpy(insert_buffer, &column[0], length);
    stream.write(insert_buffer, length);
    byteCounter += length;

    column  = rot.getCol1();
    memcpy(insert_buffer+byteCounter, &column[0], length);
    stream.write(insert_buffer, length);
    byteCounter += length;

    column  = rot.getCol2();
    memcpy(insert_buffer+byteCounter, &column[0], length);
    stream.write(insert_buffer, length);
}

到流中并用空格字符分隔每个条目。

这不能很好地工作,好像我添加了15个这样的数据结构,然后在接收器端使用split方法,这取决于我有时会获得超过15个字符串的数据,例如18,因为二进制数据本身可能在其中包含ascii空格字符。至少这就是我认为的问题所在。

如何解决这个问题?

--- ----编辑 我在开始时添加了一些整数后,在流中添加了这15个数据结构,因此我需要使用split方法来获取这些初始数。

2 个答案:

答案 0 :(得分:2)

如果发送二进制数据,则不会使用/需要'分隔符'。您将知道每种大小的写入和读取需要多少字节。例如。如果您的数字类型为uint32_t,则这些数字将来自流中的四个字节。

但是我从您的编辑中看到,您需要一些机制来解除/序列化更复杂的数据结构。我建议使用一些更合适的协议,例如Google Protocol Buffers

答案 1 :(得分:0)

有几个问题。最直接的是你 输出固定长度的二进制数据,但尝试将其解析为 输入的可变长度(部分)文本数据。通常情况下, 二进制浮点将具有固定长度(但它取决于 在二进制格式,我知道例外)。二进制 积分数据通常也有固定长度,但是 可变长度并不罕见(例如Google的协议块)。

第二个也是更普遍的问题是你只是倾销 输出流的位,没有任何格式。意思就是 在将来的某个时候,你几乎肯定无法做到 重新阅读它们。如果您要将数据溢出,此技术就可以了 磁盘,因为它不适合内存,而数据只会 稍后通过相同的过程重读。否则,你需要 定义一种格式,并根据它输出(和输入) 定义。 (这是istream::readostream::write的原因 char*void*,而非{{1}}。)