Wednesday, 31 March 2010

Protocol Buffer

This article is related to serialization using protobuf a Google's data interchange format. I've been using XML serialization for several years in my Delphi win32 applications, and I was looking for a nicer system. Then I discovered this interesting system that is able to serialize / deserialize objects in a plain format, more human readable instead of the cumbersome XML format. It's a pity that the library isn't implemented on Delphi, but at least there are a lot of programming languages where the library is now implemented. You can find a list here. For testing the power of the library I decided to give it a go in a Java project. This will help me to brush up my Java skills and go further with a protobuf implementation. But one of the primary points behind Google Protocol Buffers is to have a more efficient data packet. Their particular approach uses a stream of binary data rather than the text based on XML. This makes for much less data being sent around and for a much faster parsing. My example will show you the general idea, the easy to build and use, the quick parse and the simplicity of the project.
To some extend I think that the idea is very good, but I'll wait changing my XML serialization until there is a Delphi release of the Protocol Buffer (I'm crossing my fingers). Anyway here you can see a simple example defining the ".proto" file, and the generation of the parser class.

Graph.proto:

package Graphs;

option java_package = "example.graph";
option java_outer_classname = "Graph";

message Node {
  required string id = 1;
  required int32 weight = 2;
}

message Edge {
  required string id = 1;
  required int32 weight = 2;
  required Node source = 3;
  required Node target = 4;
}


For generating the parser class, we need to download the last protobuf compiler (for win32):

C:\protoc-2.3.0-win32>protoc Graph.proto --java_out=C:\temp

After that, we'll get the Graph.java class that will help us serializing our objects. I've created a Serializator class that will handle the node class and will serialize it using the protobuf class:

node.java:

package example.graph;

public class node {
 private String id;
 private int weight;
 
 public node(String id, int weight) {
  setId(id);
  setWeight(weight);
 }

 public void setId(String id) {
  this.id = id;
 }

 public String getId() {
  return id;
 }

 public void setWeight(int weight) {
  this.weight = weight;
 }

 public int getWeight() {
  return weight;
 }
 
 public String toString() {
  return "Id: " + id + " Weight: " + String.valueOf(weight);
 }
}

Serializator.java:

package example.graph;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import example.graph.Graph.Node;

public class Serializator {
 public void SerializeNode(node n) throws IOException {
  FileOutputStream output = new FileOutputStream("node" + String.valueOf(n.getId()));
  
  Node.Builder nodeS = Node.newBuilder();
  nodeS.setId(n.getId());
  nodeS.setWeight(n.getWeight());
  nodeS.build().writeTo(output); 
 }
 
 public node DeserializeNode(int nodeId) throws FileNotFoundException, IOException {
  Node nodeD = Node.parseFrom(new FileInputStream("node" + String.valueOf(nodeId)));
  node n = new node(nodeD.getId(), nodeD.getWeight());
  return n;
 }
}

exampleGraphMain.java:

package example.graph;

import java.io.IOException;

public class exampleGraphMain {

 /**
  * @param args
  * @throws IOException 
  */
 public static void main(String[] args) throws IOException {

  //Serialization (Creating Nodes)
  node n = new node("1", 3);
  node n2 = new node("2", 10);
  
  System.out.println(n.toString());
  System.out.println(n2.toString());
  
  Serializator sr = new Serializator();
  sr.SerializeNode(n);
  sr.SerializeNode(n2);
  
  //Deserialization (Reconstructing Nodes)
  node n3 = sr.DeserializeNode(1);
  node n4 = sr.DeserializeNode(2);

  System.out.println(n3.toString());
  System.out.println(n4.toString());  
 }
}


If you see the generated files "node1 and node2" you'll see them in a byte code format.

Enjoy the reading!.

0 comments:

Post a Comment