Protocol Buffers学习笔记
1. 简介
Protocol Buffers是google发明的一种数据交换格式,独立于语言,独立于平台。与其他的数据交换格式有所不同,Protocol Buffers是一种二进制的格式,因此在网络传输的时候效率更高,相对于json它的文件体积更小,相对于xml,它的解析速度更快。
作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于网络传输、配置文件、数据存储等领域。
2. 在java中的使用
2.1 新建test.proto文件
syntax = "proto2";package tutorial;option java_package = "com.example.tutorial";option java_outer_classname = "AddressBookProtos";message Person { required string name = 1; required int32 id = 2; optional string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { required string number = 1; optional PhoneType type = 2 [default = HOME]; } repeated PhoneNumber phones = 4; }message AddressBook { repeated Person people = 1; }
2.2 编译protot文件
下载编译器:
一般在每个发布版本的protoc-{版本号}-{平台}.zip压缩包里面包含对应的编译器。由于LZ用的是win系统,故下载了protoc-3.6.1-win32.zip
,解压之后在bin目录下会看到一个proto.exe
文件。在proto.exe
所在的目录下面就可以使用protoc
命令进行编译了。
protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/addressbook.proto
实例:
C:\Users\wangjun\Downloads>protoc -I=./ --java_out=./ ./test.proto
编译成功后会在当前目录下生成对用的java文件:
C:\Users\wangjun\Downloads\com\example\tutorial\AddressBookProtos.java
2.3 在项目中使用编译好的java文件
新建一个java工程,目录结构如下:
com ├─example │ └─tutorial │ AddressBookProtos.java │ └─wangjun └─protoc Client.java Constants.java Server.java
导入protobuf-java-3.5.1.jar
(LZ使用的是此版本,读者请自行下载适用版本)。此包可以对ProtocolBuffer消息进行序列化和反序列化。
编写实例代码:
1)Constants.java
package com.wangjun.protoc;public class Constants { public static final int PORT = 9988; }
2)Server.java
package com.wangjun.protoc;import java.net.ServerSocket;import java.net.Socket;import com.example.tutorial.AddressBookProtos;import com.google.protobuf.ByteString;public class Server { public static void main(String[] args) throws Exception { ServerSocket ss = new ServerSocket(Constants.PORT); System.out.println("server started..."); Socket socket = ss.accept(); System.out.println("a client connected!"); //从输入流中解析出Person对象 AddressBookProtos.Person person = AddressBookProtos.Person.parseFrom(ByteString.readFrom(socket.getInputStream())); if(person != null) { System.out.println("server received data:\n" + person.toString()); } } }
3)Client.java
package com.wangjun.protoc;import java.io.OutputStream;import java.net.Socket;import com.example.tutorial.AddressBookProtos;public class Client { public static void main(String[] args) throws Exception { Socket socket = new Socket("localhost", Constants.PORT); //构造一个Person对象 AddressBookProtos.Person person = AddressBookProtos.Person.newBuilder().setName("zhangsan") .setId(20).setEmail("zhangsan@xxxmail.com").build(); OutputStream os = socket.getOutputStream(); //将Person对象写到输出流中 os.write(person.toByteArray()); os.flush(); //这里注意一定要关闭流,否则服务端会报错 os.close(); System.out.println("client send person"); } }
2.4 测试
先运行server。
server started...
再运行client。
client send person
server端已经接收到消息。
server started... a client connected! server received data: name: "zhangsan"id: 20email: "zhangsan@xxxmail.com"
作者:王小冬
链接:https://www.jianshu.com/p/26165709a3d4