Google协议缓冲区无法正确读取

时间:2019-04-22 22:17:41

标签: java ubuntu protocol-buffers

我正在建立一个新的Java项目,该项目将(也许现在还不确定)利用Google协议缓冲区。我是这个API的新手,因此我从一个非常基本的测试开始。老实说,这项测试的结果令我非常失望。为什么这个非常简单的代码不起作用?

var output = new ByteArrayOutputStream();
Message.Echo.newBuilder().setMsg("MSG1?").build().writeTo(output);
System.out.println("output.length " + output.toByteArray().length);
Message.Echo.newBuilder().setMsg("MSG2!!").build().writeTo(output);
System.out.println("output.length " + output.toByteArray().length);

var input = new ByteArrayInputStream(output.toByteArray());
System.out.println("input.available " + input.available());
System.out.print(Message.Echo.parseFrom(input));
System.out.println("input.available " + input.available());
System.out.print(Message.Echo.parseFrom(input));

上面的代码产生以下输出:

output.length 7
output.length 15
input.available 15
msg: "MSG2!!"
input.available 0

它完全错过了第一个消息,或者似乎由于所有15个字节都被读取而以某种方式“覆盖”了它。另外,考虑到没有其他字节要读取,它无法在第二次调用时阻塞。

但是,将两条阅读行更改为:

System.out.print(Message.Echo.parseFrom(input.readNBytes(7)));
System.out.print(Message.Echo.parseFrom(input.readNBytes(15-7)));

正确打印两条消息。我正在使用JDK 11运行Kubuntu 18.04。我是否错过了一些非常重要的东西(官方教程中未提及),或者这是一个bug?

这是.proto文件:

syntax = "proto3";

package ...;

option java_package = "...";
option java_outer_classname = "Message";

message Echo {
    string msg = 1;
}

1 个答案:

答案 0 :(得分:0)

好的,为了使用同一组流写/读多条消息,似乎需要使用 writeDelimitedTo parseDelimitedFrom ,因为 parseFrom 读取直到达到EOF。

似乎首选的行为是为每个消息使用一个新的套接字。这听起来有点奇怪,但是我相信这背后有充分的理由。不过,应该在官方教程中对此进行更好的解释。