作者:妩媚天天想我 | 来源:互联网 | 2023-07-11 13:02
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)和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 }