如何反序列化包含多个记录的文件

时间:2013-11-07 13:09:26

标签: c++ deserialization offset thrift

我已经编写了一个thrift-definition,并使用这个定义在一个文件中序列化多个记录(我在每个记录的开头添加了整个记录的大小)。这就是我所做的。

boost::shared_ptr<apache::thrift::transport::TMemoryBuffer> transport(new apache::thrift::transport::TMemoryBuffer);
boost::shared_ptr<apache::thrift::protocol::TBinaryProtocol> protocol(new apache::thrift::protocol::TBinaryProtocol(transport));

myClass->write(protocol.get());

const std::string & data(transport->getBufferAsString());

之后我只是以二进制模式打印字符串数据。现在我想再次反序列化此文件。如果只有文件中的记录,我不会有任何问题,不幸的是我必须打印多个文件,所以我想我必须根据我保存在文件中的大小以及记录本身来处理偏移。但是,我似乎无法找到任何可以用来实现我的目标的例子,官方文档非常缺乏。有没有人帮我。如果我遗漏了一些信息,请问。

更多信息:

当然我想使用thrift来反序列化。但是,一个文件可以包含多个记录。例如:想象一下,我在thrift定义文件中定义了一个包含car-Information的结构。现在我在一个输出文件中序列化多个car-structs。序列化没有问题,因为我只是追加数据。但是,如果我想要反序列化,我必须知道一条记录的开始位置,然后是下一条记录的开始位置。那是我的问题。我不知道如何告诉节俭记录开始和结束的地方。我已经搜索了互联网,但似乎无法找到c ++的例子(到目前为止,我有一个用于python,但我无法将其转换为c ++)。一个文件的结构可以描述如下:[lenghtofrecord1] [record1] [lengthofrecord2] [record2] [...]

先谢谢

迈克尔

2 个答案:

答案 0 :(得分:2)

如果要将list<records>作为一个整体/序列化怎么样?或者是独立和随机读取它们的绝对要求?如果是,我会看到1,5(一个半)可能的解决方案:

  • 将第二个文件作为索引。它包含map< recordNumber, offset>或简单的整数对排序列表,以快速定位记录。由于这些数据远远少于记录,因此您可能始终将其缓存在内存中。

  • 半解:如果记录大小固定,则可以通过乘以recordSize * (recordNr-1)轻松计算任何记录位置。这样你甚至不需要大小前缀。如果您在记录或其他可变大小的实体中有字符串,这将不起作用,除非您通过为具有预定义(最大)大小的每个记录保留缓冲区来强制使用固定的记录大小。它有点难看,因此是“半”解决方案,但你不需要索引文件。

答案 1 :(得分:0)

虽然可能不是完美的解决方案,但这似乎对我有用:

    boost::shared_ptr<apache::thrift::transport::TMemoryBuffer> transport(new apache::thrift::transport::TMemoryBuffer);
    boost::shared_ptr<apache::thrift::protocol::TBinaryProtocol> protocol(new apache::thrift::protocol::TBinaryProtocol(transport));
    transport->resetBuffer((uint8_t*) buffer, sizeOfEntry);

Buffer是一个包含所需记录的char数组(我使用了seekg作为偏移量),sizeOfEntry是记录大小。之后我可以继续使用自动生成的thrift生成的类的read-Method。事实上,我之前有过这个解决方案,我只是搞砸了我的偏移,因此没有用。