例如,我曾经定义一个 proto
文件
option java_package = "proto.data";
message Data {
repeated string strs = 1;
repeated int ints = 2;
}
我从网络接收到该对象的输入流(或字节)。然后,通常,我会进行类似 Data.parserFrom(stream)
或 Data.parserFrom(bytes)
的解析来获取对象。
这样,当我只需要旅行时,我必须在数据对象上保留完整的内存 对象中的所有字符串和整数值。当对象尺寸很大时就不好了。
这个问题我该怎么办?
最佳答案
不幸的是,没有办法只解析 protobuf 的一部分。如果您想确保已看到strs
的全部或ints
的全部,您必须解析整个消息,因为这些值可以以任何顺序甚至交错出现。
如果您只关心内存使用情况而不关心 CPU 时间,那么理论上您可以使用手写解析器来解析消息并忽略您不关心的字段。你仍然需要做解析的工作,你可以立即丢弃它们,而不是将它们保留在内存中。但是,要做到这一点,您需要研究 Protobuf wire format并编写自己的解析器。您可以使用 Protobuf 的 CodedInputStream 类,但仍然需要手动完成大量工作。 Protobuf 库确实不是为此而设计的。
如果您愿意考虑使用不同的协议(protocol)框架,Cap'n Proto在设计上与 Protobuf 极其相似,但其特点是能够仅读取您关心的消息部分。 Cap'n Proto 不会对您不检查的字段产生任何开销,显然除了接收原始消息字节的带宽和内存之外。如果您正在从文件中读取数据,并且使用内存映射(Java 中的MappedByteBuffer
),那么只有您实际使用的消息部分才会从磁盘读取。
(披露:我是大部分 Google Protobufs v2(您可能正在使用的版本)以及 Cap'n Proto 的作者。)
关于java - 在java中部分读取proto而不是完整解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29361058/