在Java中编写带分隔符的c++ Protobuf消息和读取

Writing Delimited C++ Protobuf Messages and Reading in Java

本文关键字:Protobuf c++ 消息 读取 分隔符 Java      更新时间:2023-10-16

我正在用c++编写多个protobuf消息到一个文件。

int fifoPipe = open("/media/my_pipe", O_WRONLY);
MyModel *model = new MyModel();
// Write to fifo pipe.
model->SerializeToFileDescriptor(fifoPipe);

我读到消息大小是在消息数据之前自动写入文件的。显然情况并非如此:

https://developers.google.com/protocol-buffers/docs/techniques?hl=en

所以在Java中应该可以像这样读取消息:

MyModel.parseDelimitedFrom(fileInputStream);

但是这里有一些问题:

不能在Java中反序列化c++中的protobuf数据

在Java中是否存在与协议缓冲区分隔的I/O函数等效的c++ ?

表示必须手动写入消息大小

由于问题有点老,这个过程可能已经改变了。

在c++中编写多个消息并在Java中读取这些消息的正确方法是什么?

还要考虑Java如何响应半写的消息。理论上,它应该在返回之前等待与消息大小相等的数据。

遗憾的是,parseDelimitedFrom()writeDelimitedTo()方法还没有被添加到c++库中。

我在回答你提到的一个问题时写的代码仍然是在c++中实现这一点的最佳方式:

https://stackoverflow.com/a/22927149/2686899

Google及其所有资源没有在c++中添加这些格式的主要原因是Google内部根本不使用这种格式。对于网络通信,Google使用其内部RPC协议(非常类似于他们最近开源的GRPC),并且为了将消息存储到磁盘,他们通常使用各种内部格式,这些格式比这种"分隔"格式更有特色(例如,您可以考虑使用sqlite)。

事实上,当Protobuf第一次开源时,parseDelimitedFrom()甚至在Java中都不存在。我后来专门为开源库的用户添加了它,作为一种权宜之计——很多人问我们如何向一个文件写入多个消息,并告诉他们"你应该开发自己的框架库"似乎不太好。

Google可能是一家大公司,但当时我是唯一一个全职从事协议缓冲区的人员。不幸的是,由于我不太记得的原因,我只在Java中实现了这些函数,并且从来没有在c++中添加它们。回想起来,这似乎有点愚蠢——编写c++代码不会很难,正如您在上面的链接中看到的那样。但我有很多事要做,你可以想象。

目前的Protobuf团队于2010年接管,我转向其他事情(最终离开了Google)。我不知道为什么他们没有将这些代码添加到c++库中,但我猜是没有足够的人要求它,他们专注于其他事情。我敢打赌,如果你提交一个bug,并链接到我的代码——或者更好的是,你自己提交一个pull request——他们可能会接受它。(我自己会提交一个pull request,但是现在我没有时间写必要的单元测试,等等…)

EDIT: OK,违背我更好的判断,我花时间准备了一个拉请求:https://github.com/google/protobuf/pull/710