40 votes

Buffers du protocole Google - Stockage des messages dans un fichier

J'utilise le tampon du protocole Google pour sérialiser les données du marché des actions (c'est-à-dire l'horodatage, les champs d'offre et de demande). Je peux stocker un message dans un fichier et le désérialiser sans problème.

Comment puis-je stocker plusieurs messages dans un seul fichier ? Je ne sais pas comment séparer les messages. Je dois être en mesure d'ajouter de nouveaux messages au fichier à la volée.

34voto

Josh Hansen Points 718

Je recommande d'utiliser le writeDelimitedTo(OutputStream) y parseDelimitedFrom(InputStream) méthodes sur Message objets. writeDelimitedTo écrit la longueur du message avant le message lui-même ; parseDelimitedFrom puis utilise cette longueur pour lire un seul message et pas plus loin. Cela permet d'écrire plusieurs messages sur un seul fichier OutputStream qui seront ensuite analysés séparément. Pour plus d'informations, voir https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/MessageLite#writeDelimitedTo(java.io.OutputStream)

14voto

DD. Points 4098

Dans la documentation :

http://code.google.com/apis/protocolbuffers/docs/techniques.html#streaming

Diffusion en continu de plusieurs messages

Si vous voulez écrire plusieurs messages dans un seul fichier ou flux, il vous devez savoir où se termine un message et où commence le suivant. suivant. Le format de fil du tampon de protocole n'est pas autodélimité. les analyseurs de tampon de protocole ne peuvent pas déterminer eux-mêmes la fin d'un message propre. La manière la plus simple de résoudre ce problème consiste à écrire la taille de chaque message avant d'écrire le message lui-même. Lorsque vous lisez les les messages, vous lisez la taille, puis vous lisez les octets dans une dans un tampon séparé, puis vous lisez à partir de ce tampon. (Si vous voulez éviter de éviter de copier les octets dans un tampon séparé, consultez la classe CodedInputStream (en C++ et Java) qui peut être configurée pour limiter la lecture à un certain nombre d'octets). certain nombre d'octets).

6voto

Marc Gravell Points 482669

Protobuf n'inclut pas de terminateur par enregistrement le plus éloigné, vous devez donc le faire vous-même. L'approche la plus simple est de préfixer les données avec la longueur de l'enregistrement qui suit. Personnellement, j'ai tendance à utiliser l'approche consistant à écrire un en-tête de chaîne (pour un numéro de champ arbitraire), puis la longueur comme un "varint" - cela signifie que le document entier est alors lui-même un protobuf valide, et pourrait être consommé comme un objet avec un élément "répété", cependant, un simple marqueur de longueur fixe (typiquement 32 bits little-endian) ferait tout aussi bien l'affaire. Avec un tel stockage, il est possible d'ajouter des éléments selon vos besoins.

5voto

moof2k Points 648

Si vous recherchez une solution C++, Kenton Varda a soumis un patch à protobuf vers août 2015 qui ajoute le support des appels writeDelimitedTo() et readDelimitedFrom() qui sérialisent/désérialisent une séquence de messages proto vers/depuis un fichier d'une manière compatible avec la version Java de ces appels. Malheureusement, ce patch n'a pas encore été approuvé, donc si vous voulez cette fonctionnalité, vous devrez la fusionner vous-même.

Une autre option est que Google a ouvert le code de lecture/écriture du fichier protobuf à travers d'autres projets. Le site ou-outils contient, par exemple, les classes RecordReader y RecordWriter qui sérialisent/désérialisent un flux proto vers un fichier.

Si vous voulez des versions autonomes de ces classes qui n'ont presque pas de dépendances externes, j'ai un fork de or-tools qui ne contient que ces classes. Voir : https://github.com/moof2k/recordio

Lire et écrire avec ces classes est très simple :

File* file = File::Open("proto.log", "w");
RecordWriter writer(file);
writer.WriteProtocolMessage(msg1);
writer.WriteProtocolMessage(msg2);
...
writer.Close();

-6voto

creatiwit Points 87

Une méthode plus simple consiste à coder en base64 chaque message et à le stocker sous forme d'un enregistrement par ligne.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X