Netty with protobufjava
這是一篇關於netty和protobuf2的文章,先來介紹一下protobuf的簡單使用。網上有不少基本的protobuf的介紹,這裏就不在贅述了。性能
protobuf官網上提供了一個例子,咱們就拿那個例子來改造:ui
proto文件描述了消息的結構,這個文件時這樣的netty
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 phone = 4; } message AddressBook { repeated Person person = 1; }
咱們如今經過protobuf提供的源代碼編譯器生成咱們的Java代碼code
E:\tools2\protobuf>protoc.exe -I=E:\test-protobuf --java_out=E:\test-protobuf E:\test-protobuf\addressbook.proto
-I表示指定proto文件的目錄位置,--java-out表示輸出Java源代碼的目錄位置,後跟的參數表示文件的路徑ip
如今在你所指定的目錄下有一個Java類文件,就是AddressBookProtos.java文件。get
經過這個類能夠把這個類序列化,看示例代碼:編譯器
@Test public void test() throws IOException { AddressBookProtos.AddressBook.Builder addressBookBuilder = AddressBookProtos.AddressBook.newBuilder(); AddressBookProtos.Person.PhoneNumber.Builder phoneNumberBuilder = AddressBookProtos. Person.PhoneNumber.newBuilder(); AddressBookProtos.Person.Builder personBuilder = AddressBookProtos.Person.newBuilder(); personBuilder.setEmail("744858873@qq.com").setId(123456789).setName("hellolyx"); personBuilder.addPhone(phoneNumberBuilder.setNumber("15840330465").setType(AddressBookProtos.Person.PhoneType.HOME).build()); personBuilder.addPhone(phoneNumberBuilder.setNumber("15840330466").setType(AddressBookProtos.Person.PhoneType.WORK).build()); personBuilder.addPhone(phoneNumberBuilder.setNumber("15840330467").setType(AddressBookProtos.Person.PhoneType.MOBILE).build()); personBuilder.addPhone(phoneNumberBuilder.setNumber("15840330468").setType(AddressBookProtos.Person.PhoneType.MOBILE).build()); personBuilder.addPhone(phoneNumberBuilder.setNumber("15840330469").setType(AddressBookProtos.Person.PhoneType.MOBILE).build()); personBuilder.setPhone(0, phoneNumberBuilder.setNumber("110").setType(AddressBookProtos.Person.PhoneType.MOBILE).build()); //向電話薄裏添加一個聯繫人 addressBookBuilder.addPerson(personBuilder.build()); personBuilder.setEmail("78655676@qq.com").setId(123456789).setName("hellodog"); personBuilder.addPhone(phoneNumberBuilder.setNumber("15840330465").setType(AddressBookProtos.Person.PhoneType.HOME).build()); personBuilder.addPhone(phoneNumberBuilder.setNumber("15840330466").setType(AddressBookProtos.Person.PhoneType.WORK).build()); personBuilder.addPhone(phoneNumberBuilder.setNumber("15840330467").setType(AddressBookProtos.Person.PhoneType.MOBILE).build()); personBuilder.addPhone(phoneNumberBuilder.setNumber("15840330468").setType(AddressBookProtos.Person.PhoneType.MOBILE).build()); personBuilder.addPhone(phoneNumberBuilder.setNumber("15840330469").setType(AddressBookProtos.Person.PhoneType.MOBILE).build()); personBuilder.setPhone(0, phoneNumberBuilder.setNumber("119").setType(AddressBookProtos.Person.PhoneType.MOBILE).build()); //再次向電話薄裏添加一個聯繫人 addressBookBuilder.addPerson(personBuilder.build()); personBuilder.setEmail("78655676@qq.com").setId(123456789).setName("hellopig"); personBuilder.addPhone(phoneNumberBuilder.setNumber("15840330465").setType(AddressBookProtos.Person.PhoneType.HOME).build()); personBuilder.addPhone(phoneNumberBuilder.setNumber("15840330466").setType(AddressBookProtos.Person.PhoneType.WORK).build()); personBuilder.addPhone(phoneNumberBuilder.setNumber("15840330467").setType(AddressBookProtos.Person.PhoneType.MOBILE).build()); personBuilder.addPhone(phoneNumberBuilder.setNumber("15840330468").setType(AddressBookProtos.Person.PhoneType.MOBILE).build()); personBuilder.addPhone(phoneNumberBuilder.setNumber("15840330469").setType(AddressBookProtos.Person.PhoneType.MOBILE).build()); personBuilder.setPhone(0, phoneNumberBuilder.setNumber("124").setType(AddressBookProtos.Person.PhoneType.MOBILE).build()); addressBookBuilder.addPerson(personBuilder.build()); /** * 一個電話薄裏添加了三我的 */ byte[] book = addressBookBuilder.build().toByteArray(); String path = "E:\\test-protobuf\\test.txt"; FileOutputStream fileOutputStream = new FileOutputStream(path); fileOutputStream.write(book); fileOutputStream.close(); //反序列化 AddressBookProtos.AddressBook b = AddressBookProtos.AddressBook.parseFrom(book); System.out.println(b.toString()); }
這是經過proto.exe生成的Java類的基本用法,最後打印出來的信息略。string
經過這種方式,你能夠發現序列化一個類是否是很方便啊,而且序列化和反序列有很好的性能,同時序列後的數據量很小。it
在上個例子中,咱們吧序列化後的數據保存在了txt文件中,如今能夠經過讀取這個文本文件反序列化。
/** * 在運行時肯定消息格式,動態生成消息 */ @Test public void test8876() throws IOException { String messagePath = "E:\\test-protobuf\\test.txt"; FileInputStream fileInputStream = new FileInputStream(messagePath); byte[] message = new byte[fileInputStream.available()]; fileInputStream.read(message); Descriptors.FileDescriptor fileDescriptor = AddressBookProtos.getDescriptor(); Descriptors.Descriptor addressBookDescriptor = fileDescriptor.findMessageTypeByName("AddressBook"); DynamicMessage addressBook = DynamicMessage.parseFrom(addressBookDescriptor, message); System.out.println(addressBook.toString()); }
這就是基本的protobuf-java類庫的基本使用方法。對於protobuf的自描述消息尚未研究的很透徹,等研究明白了,再把那個發上來。
====END====