Google Protobuf ByteString vs. Byte []

时间:2015-03-12 19:16:17

标签: java string bytearray protocol-buffers

我正在使用Java中的google 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): “不可变的字节序列。通过共享对不可变的底层字节的引用来支持子字符串,就像使用String一样。”

我不清楚ByteString如何与String或byte []不同。 有人可以解释一下吗? 感谢。

2 个答案:

答案 0 :(得分:31)

您可以将ByteString视为不可变字节数组。几乎就是这样。它是byte[],您可以在protobuf中使用它。 Protobuf不允许您使用Java数组,因为它们是可变的。

存在

ByteString,因为String不适合表示任意字节序列。 String专门用于字符数据。

  

protobuf MessageLite接口提供toByteArray()和toByteString()方法。如果ByteString是一个不可变的byte [],那么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);
  }
}

答案 1 :(得分:5)

使用ByteString,您可以对基础数据执行更多操作,而无需将数据复制到新结构中。例如,如果您想在bytes中向另一个方法提供byte[]的子集,则需要为其提供起始索引和结束索引。您还可以连接ByteStrings,而无需创建新的数据结构并手动复制数据。

但是,使用ByteString,您可以为该方法提供该数据的子集,而无需了解底层存储的任何方法。就像普通String的子串一样。

字符串用于表示文本,并且不是存储二进制数据的好方法(因为并非所有二进制数据都具有文本等效项,除非您以这样的方式对其进行编码:例如hex或Base64 )。