Introduktion til Google Protocol Buffer

1. Oversigt

I denne artikel ser vi på Google Protocol Buffer (protobuf) - et velkendt sprog-agnostisk binært dataformat. Vi kan definere en fil med en protokol og derefter ved hjælp af denne protokol kan vi generere kode på sprog som Java, C ++, C #, Go eller Python.

Dette er en indledende artikel til selve formatet; hvis du vil se, hvordan du bruger formatet med en Spring-webapplikation, skal du kigge på denne artikel.

2. Definition af Maven-afhængigheder

For at bruge protokolbuffere er Java, skal vi tilføje en Maven-afhængighed til en protobuf-java:

 com.google.protobuf protobuf-java $ {protobuf.version} 3.2.0 

3. Definition af en protokol

Lad os starte med et eksempel. Vi kan definere en meget enkel protokol i et protobuf-format:

besked Person {krævet strengnavn = 1; }

Dette er en protokol med en simpel besked fra Person type, der kun har et obligatorisk felt - navn, der har en snor type.

Lad os se på det mere komplekse eksempel på at definere en protokol. Lad os sige, at vi skal gemme personoplysninger i et protobuf-format:

pakke protobuf;

pakke protobuf; mulighed java_package = "com.baeldung.protobuf"; option java_outer_classname = "AddressBookProtos"; besked Person {krævet strengnavn = 1; krævet int32 id = 2; valgfri streng e-mail = 3; gentagne strengnumre = 4; } besked Adressebog {gentagne personers folk = 1; }

Vores protokol består af to typer data: a Person og en Adressebog. Efter generering af koden (mere om dette i det senere afsnit) vil disse klasser være de indre klasser inde i AdressebogBilleder klasse.

Når vi ønsker at definere et felt, der kræves - hvilket betyder at oprettelse af et objekt uden et sådant felt vil medføre et Undtagelse, vi skal bruge en krævet nøgleord.

Oprettelse af et felt med valgfri nøgleord betyder, at dette felt ikke behøver at blive indstillet. Det gentages nøgleord er en matrixtype af variabel størrelse.

Alle felter er indekseret - det felt, der er angivet med nummer 1, gemmes som et første felt i en binær fil. Felt markeret med 2 gemmes derefter og så videre. Det giver os bedre kontrol over, hvordan felter er lagt i hukommelsen.

4. Generering af Java-kode fra en Protobuf-fil

Når vi først har defineret en fil, kan vi generere kode ud fra den.

For det første skal vi installere protobuf på vores maskine. Når vi har gjort dette, kan vi generere kode ved at udføre en protoc kommando:

protoc -I =. --java_out =. adressebog.proto

Det protoc kommando genererer Java-outputfil fra vores adressebog.proto fil. Det -JEG option angiver en mappe, hvor en proto filen findes. Det java-ud angiver en mappe, hvor den genererede klasse oprettes.

Genereret klasse vil have settere, getters, konstruktører og bygherrer til vores definerede meddelelser. Det vil også have nogle anvendelsesmetoder til at gemme protobuf-filer og deserialisere dem fra binært format til Java-klasse.

5. Oprettelse af en forekomst af Protobuf-definerede meddelelser

Vi kan nemt bruge en genereret kode til at oprette Java-forekomst af en Person klasse:

String email = "[email protected]"; int id = ny tilfældig (). nextInt (); String name = "Michael Program"; Strengnummer = "01234567890"; AddressBookProtos.Person person = AddressBookProtos.Person.newBuilder () .setId (id) .setName (name) .setEmail (email) .addNumbers (number) .build (); assertEquals (person.getEmail (), e-mail); assertEquals (person.getId (), id); assertEquals (person.getName (), navn); assertEquals (person.getNumbers (0), antal);

Vi kan oprette en flydende bygherre ved hjælp af en newBuilder () metode på den ønskede meddelelsestype. Efter indstilling af alle krævede felter kan vi kalde en bygge () metode til at oprette en forekomst af en Person klasse.

6. Serialisering og deserialisering af Protobuf

Når vi opretter en instans af vores Person klasse, vil vi gemme det på disken i et binært format, der er kompatibelt med en oprettet protokol. Lad os sige, at vi vil oprette en forekomst af Adressebog klasse og tilføj en person til det objekt.

Dernæst vil vi gemme den fil på disken - der er en skrive til() util-metode i automatisk genereret kode, som vi kan bruge:

AddressBookProtos.AddressBook addressBook = AddressBookProtos.AddressBook.newBuilder (). AddPeople (person) .build (); FileOutputStream fos = ny FileOutputStream (filePath); addressBook.writeTo (fos);

Efter at have udført denne metode, vil vores objekt blive serialiseret til binært format og gemt på disken. At indlæse disse data fra en disk og deserialisere dem tilbage til Adressebog objekt, vi kan bruge en fusionere fra () metode:

AddressBookProtos.AddressBook deserialized = AddressBookProtos.AddressBook.newBuilder () .mergeFrom (ny FileInputStream (filePath)). Build (); assertEquals (deserialized.getPeople (0) .getEmail (), e-mail); assertEquals (deserialized.getPeople (0) .getId (), id); assertEquals (deserialized.getPeople (0) .getName (), navn); assertEquals (deserialized.getPeople (0) .getNumbers (0), antal);

7. Konklusion

I denne hurtige artikel introducerede vi en standard til beskrivelse og lagring af data i et binært format - Google Protocol Buffer.

Vi oprettede en simpel protokol, oprettet Java-forekomst, der overholder den definerede protokol. Dernæst så vi, hvordan vi serieliserer og deserialiserer objekter ved hjælp af protobuf.

Implementeringen af ​​alle disse eksempler og kodestykker findes i GitHub-projektet - dette er et Maven-projekt, så det skal være let at importere og køre, som det er.