Hadoop基础-Protocol Buffers串行化与反串行化
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
我们之前学习过很多种序列化文件格式,比如python中的pickle序列化方式(),golang的Gob序列化方式(https://www.cnblogs.com/yinzhengjie/p/7807051.html),hadoop的SequenceFile序列化文件(),Java内置的ObjectOutputStream序列化方式(https://www.cnblogs.com/yinzhengjie/p/8988003.html)等等。
当然,除了语言自己内置的序列化方式外,还有一些手动二进制编码的序列化文件,以及人性化可读格式的序列化文件,比如XMl,JSON,DOM,SAX,STAX,JAXB,JAXP等等,不过这些序列化方式都不是今天的主角,我今天要介绍的是Google公司在2008年就开源的一种序列化方式,即Protocol Buffers序列化。
一.Protocol Buffers 简介
1>.什么是 Protocol Buffers
第一:A description language(一种描述语言);
第二:A complier(它是一个编译器);
第三:A library(它是一种库);
2>.Protocol Buffers 优点
第一:易于使用,高效的二进制编码;
第二:它是由谷歌公司研发的;
第三:简单高效的串行化技术,在2008公开该技术;
3>.支持跨语言
官方支持:Java, C++, and Python等等
非官方支持:C, C#, Erlang, Perl, PHP, Ruby等等
二.Protocol Buffers 代码生成
1>.创建emp.proto自描述文件(非java文件,具体内容如下)
package tutorial; option java_package = "tutorialspoint.com"; option java_outer_classname = "Emp2"; message Emp { required int32 id = 1; required string name = 2; required int32 age = 3; required int32 salary = 4; required string address = 5; }
2>.将emp.proto(下载地址:)和protobuf\src\protoc.exe放在同一个文件夹
3>.编译emp.proto(protoc --java_out=. emp.proto)
4>.将"D:\10.Java\IDE\yhinzhengjieData\ProtocolBuffers\tutorialspoint\com"(这是我本地目录)下的Emp2.java放置在idea中,包名“tutorialspoint.com”
三.编写代码
1>.编写串行化代码
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.protocolBuffers; 7 8 import tutorialspoint.com.Emp2; 9 10 import java.io.File;11 import java.io.FileOutputStream;12 13 public class MyProtocolBuffers {14 15 private static final File protocolBuffers = new File("D:\\10.Java\\IDE\\yhinzhengjieData\\ProtocolBuffers\\emp.protocolBuffers");16 17 18 public static void main(String[] args) throws Exception {19 protocolBuffersSerial();20 }21 /**22 * 定义序列化方式23 */24 public static void protocolBuffersSerial() throws Exception {25 long start = System.currentTimeMillis();26 FileOutputStream fos = new FileOutputStream(protocolBuffers);27 //注意,在序列化一个对象的时候,都是打点的方式设置的哟!在设置完毕后需要以".build"结束!28 Emp2.Emp emp = Emp2.Emp.newBuilder().29 setId(1).30 setName("尹正杰").31 setAge(18).32 setSalary(66666666).33 setAddress("北京").build();34 //我们循环写入数据35 for (int i = 0; i < 10000000; i++) {36 emp.writeTo(fos);37 }38 fos.close();39 System.out.printf("这是protocol Buffers序列化方式: 生成文件大小:[%d],用时:[%d]\n",protocolBuffers.length(),System.currentTimeMillis() - start);40 }41 }42 43 /*44 以上代码执行结果如下:45 这是protocol Buffers序列化方式: 生成文件大小:[280000000],用时:[10960]46 */
执行以上代码后,在本地目录会生成一个文件如下:
2>.编写反串行化代码
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.protocolBuffers; 7 8 import tutorialspoint.com.Emp2; 9 10 import java.io.File;11 import java.io.FileInputStream;12 import java.io.FileOutputStream;13 14 public class MyProtocolBuffers {15 16 private static final File protocolBuffers = new File("D:\\BigData\\JavaSE\\yinzhengjieData\\ProtocolBuffers\\emp.protocolBuffers");17 18 19 public static void main(String[] args) throws Exception {20 protocolBuffersSerial();21 protocolBuffersDeserial();22 }23 /**24 * 定义序列化方式25 */26 public static void protocolBuffersSerial() throws Exception {27 long start = System.currentTimeMillis();28 FileOutputStream fos = new FileOutputStream(protocolBuffers);29 //注意,在序列化一个对象的时候,都是打点的方式设置的哟!在设置完毕后需要以".build"结束!30 Emp2.Emp emp = Emp2.Emp.newBuilder().31 setId(1).32 setName("尹正杰").33 setAge(18).34 setSalary(66666666).35 setAddress("北京").build();36 //我们循环写入数据37 for (int i = 0; i < 2000000; i++) {38 emp.writeTo(fos);39 }40 fos.close();41 System.out.printf("这是protocol Buffers序列化方式: 生成文件大小:[%d],用时:[%d]\n",protocolBuffers.length(),System.currentTimeMillis() - start);42 }43 44 /**45 * 定义反序列化方式46 */47 public static void protocolBuffersDeserial() throws Exception {48 long start = System.currentTimeMillis();49 FileInputStream fis = new FileInputStream(protocolBuffers);50 51 Emp2.Emp emp = Emp2.Emp.parseFrom(fis);52 53 for (int i = 0; i < 2000000; i++) {54 emp.getId();55 emp.getName();56 emp.getAge();57 emp.getSalary();58 emp.getAddress();59 }60 System.out.printf("这是protocol Buffers反序列化方式: 生成文件大小:[%d],用时:[%d]\n",protocolBuffers.length(),System.currentTimeMillis() - start);61 }62 63 }