1

我写了一个节俭定义,并使用这个定义在一个文件中序列化多个记录(我在每个记录的开头添加了整个记录的大小)。简而言之,这就是我所做的。

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 来反序列化。但是,一个文件可以包含多条记录。例如:假设我在包含 car-Information 的 thrift-definition 文件中定义了一个结构。现在我在一个输出文件中序列化多个汽车结构。序列化没问题,因为我只是附加数据。但是,如果我想反序列化,我必须知道一条记录从哪里开始,下一条从哪里开始。那是我的问题。我不知道如何告诉 Thrift 一张唱片的开始和结束位置。我在网上搜索过,但似乎找不到 c++ 的示例(到目前为止,我有一个用于 python 的示例,但无法将其翻译为 c++)。一个文件的结构可以描述为:[lenghtofrecord1][record1][lengthofrecord2][record2][...]

提前致谢

迈克尔

4

2 回答 2

2

拥有一个list<records>你作为一个整体反/序列化的东西怎么样?还是绝对要求独立随机阅读它们?如果是,我看到 1,5(一个半)可能的解决方案:

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

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

于 2013-11-07T18:44:53.303 回答
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 是记录大小。之后,我可以继续使用我的节俭生成类的自动生成的读取方法。事实上,我早些时候有这个解决方案,我只是搞砸了我的偏移量,因此它不起作用。

于 2013-11-07T15:58:53.600 回答