使用协议缓冲区从文件读取消息时出现问题
Problems using Protocol Buffers to read messages from file
我正在尝试使用Google协议缓冲区从文件中读取多条消息。文档建议使用 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 chunkn";
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 chunkn";
return 1;
}
std::cout << "Num values in chunk " << in_chunk.values_size() << "n";
}
google::protobuf::ShutdownProtobufLibrary();
}
writeDelimitedTo
和readDelimitedFrom
来自C++ protobuf 库作者的回答:
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。
正如@rashimoto正确指出的那样,我无法以二进制模式打开我的文件!
修复后,我可以成功地将多条消息写入文件:
int main() {
GOOGLE_PROTOBUF_VERIFY_VERSION;
{
std::vector<Chunk> chunks = createChunks(NUM_CHUNKS, CHUNK_SIZE);
std::ofstream output("D:\temp.bin", std::ios::binary);
OstreamOutputStream raw_output(&output);
for (Chunk& chunk : chunks) {
if (!writeDelimitedTo(chunk, &raw_output)){
std::cout << "Unable to write chunkn";
return 1;
}
}
}
{
std::ifstream input("D:\temp.bin", std::ios::binary);
IstreamInputStream raw_input(&input);
std::vector<Chunk> chunks(NUM_CHUNKS);
for (auto& chunk : chunks) {
if (!readDelimitedFrom(&raw_input, &chunk)) {
std::cout << "Unable to read chunkn";
return 1;
}
}
std::cout << "Num values in first chunk " << chunks[0].values_size() << "n";
}
google::protobuf::ShutdownProtobufLibrary();
}
相关文章:
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 发送和十六进制消息时套接字代码C++问题
- 使用OpenSSL的SHA 512 HMAC消息身份验证的问题
- Firebase C 云消息传递背景问题
- 我无法弄清楚我的程序的问题,即使我已经查看了错误日志消息
- QT 信号插槽问题。发出信号,不调用时隙。没有警告,没有错误,没有消息
- 消息框和MB_HELP的问题
- AOT问题,消息"正在Xamarin iOS上尝试使用Pinvoke JIT编译方法"
- 发送和将消息从一个类发送到另一堂课的问题.MFC程序
- 消息框线程问题
- 如何解决从客户端接收消息时窗口冻结问题(无响应)
- 如果对象将在消息处理程序中使用,如何解决内存泄漏问题
- Google Protobuf3消息中出现多个字符串问题
- 鼠标挂钩和消息框问题
- 设计问题:消息处理组件..调用不正确的重载函数
- 使用SetWindowsHookEx钩子键盘消息的问题
- Windows (c++)上窗口消息的问题(延迟)
- 使用协议缓冲区从文件读取消息时出现问题
- msmqc++接收消息问题