我正在用Java与谷歌protobuf合作。我发现可以将protobuf消息序列化为String、byte[]和ByteString等:(来源:https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/MessageLite)
我不知道ByteString是什么。我从protobuf API文档中得到了以下定义(来源:https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/ByteString):“不可变字节序列。通过共享对不可变基础字节的引用(如字符串)来支持子字符串。”
我不清楚ByteString与String或byte[]有什么不同。有人能解释一下吗?谢谢。
ByteString
使您能够对底层数据执行更多操作,而无需将数据复制到新结构中。例如,如果您想在字节[]
中向另一个方法提供字节的子集,则需要为其提供开始索引和结束索引。您还可以连接
字节测试环
,而无需创建新的数据结构并手动复制数据。
但是,使用
ByteString
,您可以为方法提供该数据的子集,而方法不需要了解底层存储。就像普通字符串的子字符串一样。
字符串用于表示文本,并不是存储二进制数据的好方法(因为并非所有二进制数据都具有文本等价物,除非您以某种方式对其进行编码:例如十六进制或Base64)。
您可以将ByteString
视为一个不可变的字节数组。差不多就是这样。这是一个字节[]
,可以在protobuf中使用。Protobuf不允许使用Java数组,因为它们是可变的。
ByteString
的存在是因为String
不适合表示任意字节序列<代码>字符串专门用于字符数据。
protobuf MessageLite接口提供toByteArray()和toByteString()方法。如果ByteString是一个不可变字节[],那么ByteString和byte[]表示的消息的字节表示形式是否相同?
某种程度上。如果调用toByteArray()
将得到与调用toByteString()相同的值。toByteArray()
。在AbstractMessageLite
中比较这两种方法的实现:
public ByteString toByteString() {
try {
final ByteString.CodedBuilder out =
ByteString.newCodedBuilder(getSerializedSize());
writeTo(out.getCodedOutput());
return out.build();
} catch (IOException e) {
throw new RuntimeException(
"Serializing to a ByteString threw an IOException (should " +
"never happen).", e);
}
}
public byte[] toByteArray() {
try {
final byte[] result = new byte[getSerializedSize()];
final CodedOutputStream output = CodedOutputStream.newInstance(result);
writeTo(output);
output.checkNoSpaceLeft();
return result;
} catch (IOException e) {
throw new RuntimeException(
"Serializing to a byte array threw an IOException " +
"(should never happen).", e);
}
}