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:
For generating the parser class, we need to download the last protobuf compiler (for win32):
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:
Serializator.java:
exampleGraphMain.java:
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!.
Comments
Post a Comment