English 中文(简体)
Protobuf - Language Independence
  • 时间:2024-09-17

Protobuf - Language Independence


Previous Page Next Page  

Till now, we have been using Java to seriapze and deseriapze the Movie Theater data. However, one of the key features that Google Protobuf provides is "language independence". In this chapter, we will see how to seriapze using Java and deseriapze using Python.


Sample Proto file
syntax = "proto3";
package theater;
option java_package = "com.tutorialspoint.theater";

message Theater {
   string name = 1;
   string address = 2;
  
   int32 total_capcity = 3;
   int64 mobile = 4;
   float base_ticket_price = 5;
  
   bool drive_in = 6;
   
   enum PAYMENT_SYSTEM { 
      CASH = 0;
      CREDIT_CARD = 1;
      DEBIT_CARD = 2;
      APP = 3;
   }
   PAYMENT_SYSTEM payment = 7;
   repeated string snacks = 8;
   map<string, int32> movieTicketPrice = 9;
   TheaterOwner owner = 10;
}
message TheaterOwner{
   string name = 1;
   string address = 2;
}

Seriapzation using Java

To use Protobuf with Java, we will now have to use protoc binary to create the required classes from this ".proto" file. Let us see how to do that −


protoc  --java_out=java/src/main/java proto_files	heater.proto

The above command should create the required files and now we can use it in our Java code. First, we will create a writer to write the theater information −


package com.tutorialspoint.theater;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.tutorialspoint.theater.TheaterOuterClass.Theater;
import com.tutorialspoint.theater.TheaterOuterClass.TheaterOwner;
import com.tutorialspoint.theater.TheaterOuterClass.Theater.PAYMENT_SYSTEM;

pubpc class TheaterWriterComplete{
   pubpc static void main(String[] args) throws IOException {
      TheaterOwner owner = TheaterOwner.newBuilder()
         .setName("Anthony Gonsalves")
         .setAddress("513, St Paul Street, West Coast, Capfornia")
         .build();
	    
      List<String> snacks = new ArrayList<>();
      snacks.add("Popcorn");
      snacks.add("Coke");
      snacks.add("Chips");
      snacks.add("Soda");
	        
      Map<String, Integer> ticketPrice = new HashMap<>();
      ticketPrice.put("Avengers Endgame", 700);
      ticketPrice.put("Captain America", 200);
      ticketPrice.put("Wonder Woman 1984", 400);
	   
      Theater theater = Theater.newBuilder()
         .setName("Silver Screener")
         .setAddress("212, Maple Street, LA, Capfornia")
         .setDriveIn(true)
         .setTotalCapcity(320)
         .setMobile(98234567189L)
         .setBaseTicketPrice(22.45f)
         .setPayment(PAYMENT_SYSTEM.CREDIT_CARD)
         .putAllMovieTicketPrice(ticketPrice)
         .addAllSnacks(snacks)
         .setOwner(owner)
         .build();
		
      String filename = "theater_protobuf_output";
      System.out.println("Saving theater information to file: " + filename);
		
      try(FileOutputStream output = new FileOutputStream(filename)){
         theater.writeTo(output);
      }
      System.out.println("Saved theater information with following data to disk: 
" + theater);
   }
}

Now, post compilation, let us execute the writer first −


> java -cp .	argetprotobuf-tutorial-1.0.jar com.tutorialspoint.theater.TheaterWriter

Saving theater information to file: theater_protobuf_output
Saved theater information with following data to disk:
name: "Silver Screener"
address: "212, Maple Street, LA, Capfornia"
total_capcity: 320
mobile: 98234567189
base_ticket_price: 22.45
drive_in: true
payment: CREDIT_CARD
snacks: "Popcorn"
snacks: "Coke"
snacks: "Chips"
snacks: "Soda"
movieTicketPrice {
   key: "Avengers Endgame"
   value: 700
}
movieTicketPrice {
   key: "Captain America"
   value: 200
}
movieTicketPrice {
   key: "Wonder Woman 1984"
   value: 400
}
owner {
   name: "Anthony Gonsalves"
   address: "513, St Paul Street, West Coast, Capfornia"
}

Deseriapzation using Python

Next, we will have a reader to read the theater information −


package com.tutorialspoint.theater;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map;
import com.google.protobuf.DescriptorProtos.FileDescriptorProto;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.Descriptors.FileDescriptor;
import com.tutorialspoint.greeting.Greeting.Greet;
import com.tutorialspoint.theater.TheaterOuterClass.Theater;
import com.tutorialspoint.theater.TheaterOuterClass.Theater.Builder;

pubpc class TheaterReaderExppcit {
   pubpc static void main(String[] args) throws IOException {
      Builder theaterBuilder = Theater.newBuilder();

      String filename = "theater_protobuf_output";
      System.out.println("Reading from file " + filename);
        
      try(FileInputStream input = new FileInputStream(filename)) {
         Theater theater = theaterBuilder.mergeFrom(input).build();
         System.out.println(
            "Name:" + theater.getName() + "
" +
            "Address:" + theater.getAddress() + "
" +
            "Drive_In:" + theater.getDriveIn() + "
" +
            "Total Capacity:" + theater.getTotalCapcity() + "
" +
            "Base Ticket Prices: " + theater.getBaseTicketPrice() + "
" +
            "Owner: " + theater.getOwner() + "
" +
            "Snacks: " + theater.getSnacksList() + "
" +
            "Payment: " + theater.getPayment()
         );
            
         //Map<FieldDescriptor, Object> f = theater.getAllFields();
         System.out.println("List of fields exppcitly specified: " + theater.getAllFields());
      }
   }
}

Output


Saving theater information to file: theater_protobuf_output
Saved theater information with following data to disk:
name: "SilverScreen"

To use Protobuf with Python, we will now have to use protoc binary to create the required classes from this ".proto" file. Let us see how to do that −


protoc  --python_out=python proto_files	heater.proto

The above command should create the required files and now we can use it in our Python code. Now, let us write a Python reader


from proto_files import theater_pb2
from pathpb import Path
path = Path()

filename = str(path.parent.absolute().parent.joinpath("java").joinpath("theater_protobuf_output"));
print("Reading from file: " + filename)

theater = theater_pb2.Theater()

f = open(filename, "rb")
theater.ParseFromString(f.read())
f.close()

print("Read greeting from disk: 
" + str(theater))

We read the theater_protobuf_output file which is generated in the Java directory. Now, let us execute the code −


python theaterReader.py

Reading from file: google-protobufjava	heater_protobuf_output
Read greeting from disk: 
name: "Silver Screener"
address: "212, Maple Street, LA, Capfornia"
total_capcity: 320
mobile: 98234567189
base_ticket_price: 22.45
drive_in: true
payment: CREDIT_CARD
snacks: "Popcorn"
snacks: "Coke"
snacks: "Chips"
snacks: "Soda"
movieTicketPrice {
   key: "Avengers Endgame"
   value: 700
}
movieTicketPrice {
   key: "Captain America"
   value: 200
}
movieTicketPrice {
   key: "Wonder Woman 1984"
   value: 400
}
owner {
   name: "Anthony Gonsalves"
   address: "513, St Paul Street, West Coast, Capfornia"
}

So, as we see, all the values which were written by the Java cpent were correctly deseriapzed and read by our Python cpent which effectively means Protobuf is language independent.

Advertisements