Reprint, please indicate the source: http://blog.csdn.net/eclipser1987/article/details/8525383 (eclipser@163.com)
1. Download and install:
Google protocol buffer official site is: http://code.google.com/p/protobuf/
Download stable version: protobuf-2.4.1 linuxdownload protobuf-2.4.1.tar.bz2 windows download protobuf-2.4.1.zip
Here we use Linux as an example:
Tar-xvf protobuf-2.4.1.tar.bz2
CD protobuf-2.4.1
../Configure -- prefix =/usr/local/protobuf-2.4.1
Make
Make install
2. Use protobuf
View the compiled directory
CD/usr/local/protobuf-2.4.1
Ls
Bin include lib
The protoc in Bin is the processor of the. proto file. This tool can be used to generate CPP, Java, and Python files.
Because the system often uses this tool, you can copy the ln or directly to the system environment bin.
Ln-S/usr/local/protobuf-2.4.1/bin/protoc/usr/bin/protoc
Similarly, you can copy the header file ln or directly to the system environment.
Ln-S/usr/local/protobuf-2.4.1/include/Google/usr/include/Google
Copy the Lib file ln or directly to the system environment
The method is the same as above.
At this time, the protobuf development environment has been set up.
3. How to Use protobuf
Data Structure: Message message_name {message_body;} message_body format: for example, required int32 query = 1 [defaut = 10]; format: Rule type name = value [other_rule]; rule: required indicates that the value must have this value; optional indicates the optional value range; repeated indicates the value range that can be repeated (that is,> = 0); where requered/optional is a common rule, repeated is not commonly used, because repeated int32 samples = 4 [packed = true] is currently used in the history; format; value: the minimum value of value is 1, when the underlying encoding is used, 1-15 occupies one place, and> 15 occupies multiple places. Value values in different messages do not interfere with each other and are usually counted as 1. The basic data type :. proto type C ++ type Java type double float int32 intint64 int64 int64 long uint32 uint32 int uint64 uint64 long sint32 intint64 int64 int64 long fixed32 uint32 int fixed64 uint64 long sfixed32 int32 int sfixed64 int64 long bool Boolean string bytes string bytestring: complex types include enumeration, other messages, and groups. For example, Enum corpus {web = 0; Local = 1} is defined in message. Other messages can be used as types to define members. Groups I understand a bit like the Union structure in C ++. Nested definition: the message structure can be nested, while the nested defined message must be in the form of outmessage. inmessage when other messages are used as member types. Package Structure: definition form: Package Foo. bar; in C ++, two namespaces Foo and bar are generated, and the bar is defined in Foo. You can import it using import "myproject/other_protos.proto. the proto file. When referencing messages in other packages, the complete package path is required. Services: this file is mainly used in the RPC system. interface defined in proto, for example, service searchservice {RPC search (searchrequest) Return (searchresponse );}. PROTO file Compilation: Format: protoc -- proto_path = (. PROTO file path) -- cpp_out = (. cc. java generate file path )(. PROTO file path )/?. Proto -- proto_path is simplified to: -- I, where the cpp_out option can be changed to java_out/python_out as needed. Example: protoc-I =./-- cpp_out =./model. proto
Let's take an example:
Create model. proto
Package CN. vicky. model. seri; message user {required int32 id = 1; // primary key, unique required string username = 2; // account required string Password = 3; // password optional string email = 4; // mailbox (optional) repeated person = 5; // role owned by the account (repeated)} message person {required int32 id = 1; // primary key, unique required string name = 2; // role name repeated phonenumber phone = 3; // phone number (repeated)} // Enum phonetype {mobile = 0; home = 1; Work = 2;} message phonenumber {required string number = 1; optional phonetype type = 2 [default = Home];}
Protoc-I =./-- cpp_out =./model. proto
The corresponding model. Pb. H model. Pb. CC will be generated.
Usage:
Write main. cpp
/** File: Main. CPP * Author: Vicky. H * mail: eclipser@163.com */# include <iostream> # include <fstream> # include "model. pb. H "/***/INT main (void) {// create the user object CN: Vicky: Model: Seri: User U; U. set_id (1); U. set_username ("Jack"); U. set_password ("123456"); U. set_email ("289997171@qq.com"); // create a role in the user CN: Vicky: Model: Seri: person * _ person1 = u. add_person (); _ person1-> set_id (1); _ person1-> set_nam E ("p1"); // create a phone number in the role: 1 CN: Vicky: Model: Seri :: phonenumber * _ phone1 = _ person1-> add_phone (); _ phone1-> set_number ("+ 8613618074943"); _ phone1-> set_type (CN: Vicky: Model :: seri: Mobile); // create a phone number in the role: 2 CN: Vicky: Model: Seri :: phonenumber * _ phone2 = _ person1-> add_phone (); _ phone2-> set_number ("02882334717"); _ phone2-> set_type (CN: Vicky: Model :: seri: work); // create a role CN: Vicky: Model: Seri: In the user :: Person * _ person2 = u. add_person (); _ person2-> set_id (2); _ person2-> set_name ("p2"); // create a phone number in the role: 1 CN: Vicky :: model: Seri: phonenumber * _ phone3 = _ person2-> add_phone (); _ phone3-> set_number ("+ 8613996398667"); _ phone3-> set_type (CN :: vicky: Model: Seri: Mobile); // create a phone number in the role: 2 CN: Vicky: Model: Seri :: phonenumber * _ phone4 = _ person2-> add_phone (); _ phone4-> set_number ("02882334717"); _ phone4-> set_typ E (CN: Vicky: Model: Seri: work); // Persistence: // STD: fstream out ("user. PB ", STD: IOS: Out | STD: IOS: Binary | STD: IOS: trunc); // U. serializreceivstream (& out); // out. close (); // object: CN: Vicky: Model: Seri: User U2; STD: fstream in ("user. PB ", STD: IOS: In | STD: IOS: Binary); If (! U2.parsefromistream (& in) {STD: cerr <"failed to parse user. pb. "<STD: Endl; exit (1);} STD: cout <u2.id () <STD: Endl; STD: cout <u2.username () <STD: Endl; STD: cout <u2.password () <STD: Endl; STD: cout <u2.email () <STD: Endl; STD: cout <"-------------------------" <STD: Endl; For (INT I = 0; I <u2.person _ SIZE (); I ++) {CN :: vicky: Model: Seri: person * P = u2.mutable _ person (I); STD: cout <p-> ID () <STD: Endl; STD: cout <p-> name () <STD: Endl; For (Int J = 0; j <p-> phone_size (); j ++) {CN: Vicky: Model: Seri: phonenumber * phone = p-> mutable_phone (j); STD: cout <phone-> Number () <STD: Endl;} STD: cout <"-------------------------" <STD: Endl;} return 0 ;}
-Lpthread-lprotobuf (protobuf has been loaded to/usr/lib)
After execution, user. Pb is generated, and the stored binary file can be opened directly.
We have used protobuf to complete object serialization and deserialization in C ++. Here we will describe the advantages of protobuf.
Protobuf is highly efficient, and its serialization speed is several times faster than Java's own, and supports object conversion in three languages. in the past, serialized objects in C ++, for example, objects with boost serialization persistence, cannot be expanded in Java. Even if JNI technology is used, this is very troublesome. now we have protobuf.
Run: protoc-I =./-- java_out =./model. proto to generate the corresponding Java class
We can use Maven to create a Java project. The protobuf Java dependency library is required:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.vicky</groupId> <artifactId>google_protobuf_01_java</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>google_protobuf_01_java</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>2.4.1</version> </dependency> </dependencies></project>
Write test. Java
package cn.vicky.model.seri;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;/** * * @author Vicky.H */public class Test { public static void main(String args[]) throws FileNotFoundException, IOException { File file = new File("User.pb"); InputStream is = new FileInputStream(file); Model.User user = Model.User.parseFrom(is); System.out.println(user.getId()); System.out.println(user.getUsername()); System.out.println(user.getPassword()); System.out.println(user.getEmail()); System.out.println("-------------------"); for (Model.Person person : user.getPersonList()) { System.out.println(person.getId()); System.out.println(person.getName()); for (Model.PhoneNumber phone : person.getPhoneList()) { System.out.println(phone.getNumber()); } System.out.println("-------------------"); } is.close(); }}
Run:
1
Jack
123456
289997171@qq.com
---------------------------
1
P1
+ 8613618074943
02882334717
---------------------------
2
P2
+ 8613996398667
02882334717
---------------------------
Run successful (total time: 594 ms)
OK. We have finished using probuf in C ++ and Java. Is it very powerful !!
Design Philosophy:
In pojo, the class generated by protobuf is in the Po state, and the generated class should not be modified or too large. At this time, we can add a jo class to the po by using the c ++ youyuan class. separate the data structure algorithm. That is to say, Po is data, and Jo is used to put the algorithm !!!
Integration with databases:
MySQL oracle can easily store and read binary data. Another point is that, in this way, we can easily store c ++ objects, persistent redis and other memory databases.
Appendix:
Model. proto can also be defined in this way. However, I think the above is better. It is only for reference here. The structure of the generated classes is not the same in what way.
Package CN. vicky. model. seri; message user {required int32 id = 1; // primary key, unique required string username = 2; // account required string Password = 3; // password optional string email = 4; // email (optional) message person {required int32 id = 1; // primary key, unique required string name = 2; // role name // Enum phonetype {mobile = 0; home = 1; Work = 2;} message phonenumber {required string number = 1; optional phonetype type = 2 [default = Home];} repeated phonenumber phone = 3; // phone number (repeated)} repeated person = 5; // roles owned by the account (which can be repeated )}