2011-12-01 43 views
4

我从protobuf二进制文件io得到一些奇怪的行为。我正在将文本语料库预处理为protobuf中介文件。我的序列化类看起来如下:协议缓冲区问题,多个序列化成一个二进制文件

class pb_session_printer 
    { 
    public: 
    pb_session_printer(std::string & filename) 
     : out(filename.c_str(), std::fstream::out | std::fstream::trunc | 
           std::fstream|binary) 
     {} 

    void print_batch(std::vector<session> & pb_sv) 
    { 
     boost::lock_guard<boost::mutex> lock(m); 

     BOOST_FOREACH(session & s, pb_sv) 
     { 
     std::cout << out.tellg() << ":"; 
     s.SerializeToOstream(&out); 
     out.flush(); 
     std::cout << s.session_id() << ":" << s.action_size() << std::endl; 
     } 
     exit(0); 
    } 

    std::fstream out; 
    boost::mutex m; 
    }; 

输出的一个片段是这样的:

0:0:8 
132:1:8 
227:2:6 
303:3:6 
381:4:19 
849:5:9 
1028:6:2 
1048:7:18 
1333:8:28 
2473:9:24 

第一个字段显示,系列化正在按正常的。

当我运行我的程序载入程序:

int main() 
{ 
    std::fstream in_file("out_file", std::fstream::in | std::ios::binary); 
    session s; 

    std::cout << in_file.tellg() << std::endl; 
    s.ParseFromIstream(&in_file); 
    std::cout << in_file.tellg() << std::endl; 
    std::cout << s.session_id() << std::endl; 

    s.ParseFromIstream(&in_file); 
} 

我得到:

0 
-1 
111 
libprotobuf ERROR google/protobuf/message_lite.cc:123] Can't parse message of type 
"session" because it is missing required fields: session_id 

SESSION_ID:111是朝流的末尾的条目,我不了解清楚的语义图书馆的二进制io设施。请帮忙。

回答

4

如果您在一个文件中编写多个protobuffers,您需要编写protobuf + protobuffer的大小并单独读取它们(因为Cat Plus Plus中没有提到ParseFromIstream)。当你阅读原始助手时,你可以用ParseFromArray来解析它。

你的文件看起来大小此(空格仅供阅读):

大小protobuf的尺寸大小的protobuf等protobuf的

3

Message::ParseFromIstreamis documented消耗整个输入。由于您正在对相同类型的消息序列进行序列化,因此只需创建该类型的repeated字段的新消息并使用该消息。

+0

是的,我读了,让我不知道为好。该文本语料库是17Gig与340万行:(你建议意味着整个语料库将需要一次在内存中,否? –

+0

@HassanSyed:可能。另一种选择是实现自己的解析函数,只消耗一个 –

+0

有趣的是,它在流中先前遍历了所有的“会话”,并且最终返回了会话111.我本以为它会读取第一个会话并将文件头移过结束 –