web-dev-qa-db-fra.com

Google Protobuf ByteString contre Byte []

Je travaille avec google protobuf en Java. Je vois qu'il est possible de sérialiser un message protobuf en String, byte [], ByteString, etc: (Source: https://developers.google.com/protocol-buffers/docs/reference/Java/com/google/protobuf/MessageLite )

Je ne sais pas ce qu'est un ByteString. J'ai obtenu la définition suivante dans la documentation de l'API protobuf (source: https://developers.google.com/protocol-buffers/docs/reference/Java/com/google/protobuf/ByteString ): "Séquence d'octets immuable. La sous-chaîne est prise en charge en partageant la référence aux octets sous-jacents immuables, comme avec String."

Pour moi, la différence entre une chaîne d'octets et une chaîne ou un octet [] n'est pas claire. Quelqu'un peut-il expliquer? Merci.

26
Rahim Pirbhai

Vous pouvez considérer ByteString comme un tableau d'octets immuable. C'est à peu près tout. C'est un byte[] Que vous pouvez utiliser dans un protobuf. Protobuf ne vous permet pas d'utiliser les tableaux Java parce qu'ils sont mutables.

ByteString existe parce que String ne convient pas pour représenter des séquences arbitraires d'octets. String est spécifiquement pour les données de caractères.

L'interface MessageLite de protobuf fournit les méthodes toByteArray () et toByteString (). Si ByteString est un octet immuable [], la représentation en octets d'un message représenté à la fois par ByteString et byte [] serait-elle la même?

Sorte de. Si vous appelez toByteArray() vous obtiendrez la même valeur que si vous deviez appeler toByteString().toByteArray(). Comparez l'implémentation des deux méthodes, dans 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);
  }
}
32
Matt Ball

Un ByteString vous donne la possibilité d'effectuer plus d'opérations sur les données sous-jacentes sans avoir à copier les données dans une nouvelle structure. Par exemple, si vous souhaitez fournir un sous-ensemble de bytes dans un byte[] à une autre méthode, vous devrez lui fournir un index de début et un index de fin. Vous pouvez également concaténer ByteStrings sans avoir à créer une nouvelle structure de données et à copier manuellement les données.

Cependant, avec un ByteString vous pouvez donner à la méthode un sous-ensemble de ces données sans que la méthode sache quoi que ce soit sur le stockage sous-jacent. Tout comme une sous-chaîne d'une chaîne normale.

Une chaîne sert à représenter du texte et est pas un bon moyen de stocker des données binaires (car toutes les données binaires n'ont pas d'équivalent textuel, sauf si vous les codez d'une manière qui le fait: par exemple hex ou Base64).

5
Chris Thompson