1
我试图使用Google Protocol Buffers从文件读取多个消息。文档suggests使用CodedInputStream
。使用协议缓冲区从文件读取消息的问题
但是,如果我尝试读取比一个非常小的信息,我从MergeFromCodedStream
例如获得一个失败者,如果我有一个消息定义为:
message Chunk {
repeated int64 values = 1 [packed=true];
}
并尝试写留言到文件,然后读回:
int main() {
GOOGLE_PROTOBUF_VERIFY_VERSION;
{
Chunk chunk;
for (int i = 0; i != 26; ++i)
chunk.add_values(i);
std::ofstream output("D:\\temp.bin");
OstreamOutputStream raw_output(&output);
if (!writeDelimitedTo(chunk, &raw_output)){
std::cout << "Unable to write chunk\n";
return 1;
}
}
{
std::ifstream input("D:\\temp.bin");
IstreamInputStream raw_input(&input);
Chunk in_chunk;
if (!readDelimitedFrom(&raw_input, &in_chunk)) { // <--- Fails here
std::cout << "Unable to read chunk\n";
return 1;
}
std::cout << "Num values in chunk " << in_chunk.values_size() << "\n";
}
google::protobuf::ShutdownProtobufLibrary();
}
,其中由非盟来自this answerwriteDelimitedTo
和readDelimitedFrom
C++ protobuf库的thor:
bool writeDelimitedTo(
const google::protobuf::MessageLite& message,
google::protobuf::io::ZeroCopyOutputStream* rawOutput) {
google::protobuf::io::CodedOutputStream output(rawOutput);
const int size = message.ByteSize();
output.WriteVarint32(size);
uint8_t* buffer = output.GetDirectBufferForNBytesAndAdvance(size);
if (buffer != NULL) {
message.SerializeWithCachedSizesToArray(buffer);
} else {
message.SerializeWithCachedSizes(&output);
if (output.HadError()) return false;
}
return true;
}
bool readDelimitedFrom(
google::protobuf::io::ZeroCopyInputStream* rawInput,
google::protobuf::MessageLite* message) {
google::protobuf::io::CodedInputStream input(rawInput);
uint32_t size;
if (!input.ReadVarint32(&size)) return false;
google::protobuf::io::CodedInputStream::Limit limit =
input.PushLimit(size);
if (!message->MergeFromCodedStream(&input)) return false; // <-- Fails here
if (!input.ConsumedEntireMessage()) return false;
input.PopLimit(limit);
return true;
}
如果我只写25个值给我的消息,它的工作原理26,它失败。我已经展示了它在代码中失败的地方。
我试过调试到protobuf库,它似乎没有读取新的数据到缓冲区,但我不知道为什么。
我正在使用Visual Studio 2013和protobuf 2.6.1。
你是说你改变了循环在的'主()',这样的限制是从'我改变了顶峰! = 26;'其他的东西比如'i!= 30;'你不能读出你添加的30个值?是否有'MergeFromCodedStream()'函数产生的错误代码?如果你在22条消息中写入更少的值,会发生什么?顺便说一下,我建议你修改你的两个函数'writeDelimitedTo()'和'readDelimitedFrom()'来返回一个特定的错误代码,它将指示函数失败的地方,而不是仅仅返回一个'bool'。 –
@RichardChambers基本上,是的。如果我将循环更改为“i!= 25”,则按预期工作。正如所写的,'i!= 26'它失败了。据我所知,MergeFromCodedStream没有返回任何错误代码。只是一个表明成功或失败的布尔。 –
你可能需要在'std :: ofstream'和'std :: ifstream'构造函数中添加'std :: ios :: binary'行结束标志。 – rhashimoto