我正在建立一个新的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;
}
答案 0 :(得分:0)
好的,为了使用同一组流写/读多条消息,似乎需要使用 writeDelimitedTo 和 parseDelimitedFrom ,因为 parseFrom 读取直到达到EOF。
似乎首选的行为是为每个消息使用一个新的套接字。这听起来有点奇怪,但是我相信这背后有充分的理由。不过,应该在官方教程中对此进行更好的解释。