Google Protobuf ByteString против Byte []

Я работаю с google protobuf в Java. Я вижу, что можно сериализовать сообщение protobuf для String, byte [], ByteString и т.д.: (Источник: https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/MessageLite)

Я не знаю, что такое ByteString. Я получил следующее определение из документации API protobuf (источник: https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/ByteString): "Неизменяемая последовательность байтов. Подстрока поддерживается путем совместного использования ссылки на неизменяемые базовые байты, как и со строкой".

Мне непонятно, как ByteString отличается от String или byte []. Может кто-нибудь объяснить? Спасибо.

Ответы

Ответ 1

Вы можете думать о ByteString как неизменяемом массиве байтов. Это в значительной степени. Это a byte[], который вы можете использовать в protobuf. Protobuf не позволяет использовать Java-массивы, поскольку они изменяемы.

ByteString существует, потому что String не подходит для представления произвольных последовательностей байтов. String предназначен специально для символьных данных.

Интерфейс MessageLite protobuf предоставляет методыByteArray() и toByteString(). Если ByteString является неизменным байтом [], будет ли байтовое представление сообщения, представленного как ByteString, так и байтом [], одинаковым?

Сорт. Если вы вызываете 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);
  }
}

Ответ 2

A ByteString дает вам возможность выполнять больше операций с базовыми данными без необходимости копирования данных в новую структуру. Например, если вы хотите предоставить подмножество bytes в byte[] для другого метода, вам нужно будет предоставить ему индекс начала и конечный индекс. Вы также можете объединить ByteStrings без необходимости создавать новую структуру данных и вручную копировать данные.

Однако при ByteString вы можете дать методу подмножество этих данных без метода, зная что-либо о базовом хранилище. Точно так же, как подстрока нормальной строки.

Строка предназначена для представления текста и не является хорошим способом хранения двоичных данных (поскольку не все двоичные данные имеют текстовый эквивалент, если вы не кодируете его так, как это делает: например, hex или Base64).