Hadoop基础-Protocol Buffers串行化与反串行化

                    Hadoop基础-Protocol Buffers串行化与反串行化

                                          作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

  我们之前学习过很多种序列化文件格式,比如python中的pickle序列化方式(https://www.cnblogs.com/yinzhengjie/p/8531308.html),golang的Gob序列化方式(https://www.cnblogs.com/yinzhengjie/p/7807051.html),hadoop的SequenceFile序列化文件(https://www.cnblogs.com/yinzhengjie/p/9114301.html),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(下载地址:链接:https://pan.baidu.com/s/1crYmFwI68kUnzwJgoyOdpw 密码:bh63)和protobufsrcprotoc.exe放在同一个文件夹

3>.编译emp.proto(protoc --java_out=. emp.proto)

4>.将"D:10.JavaIDEyhinzhengjieDataProtocolBuffers utorialspointcom"(这是我本地目录)下的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]
",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]
",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]
",protocolBuffers.length(),System.currentTimeMillis() - start);
61     }
62 
63 }
原文地址:https://www.cnblogs.com/yinzhengjie/p/9131220.html