Google Protobuf ByteString 与 Byte[]

Google Protobuf ByteString vs. Byte[]

我正在 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)中得到以下定义: "Immutable sequence of bytes. Substring is supported by sharing the reference to the immutable underlying bytes, as with String."

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

你可以把ByteString想象成一个不可变的字节数组。差不多就是这样。这是一个可以在 protobuf 中使用的 byte[]。 Protobuf 不允许您使用 Java 数组,因为它们是可变的。

ByteString 存在是因为 String 不适合表示任意字节序列。 String 专门针对字符数据。

The protobuf MessageLite Interface provides toByteArray() and toByteString() methods. If ByteString is an immutable byte[], would the byte representation of a message represented by both ByteString and byte[] be the same?

有点。如果您调用 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);
  }
}

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

但是,使用 ByteString 您可以为该方法提供该数据的一个子集,而该方法对底层存储一无所知。就像普通字符串的子字符串一样。

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