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