一.是什么
序列化:就是将对象转化成字节序列的过程。
反序列化:就是讲字节序列转化成对象的过程。
对象序列化成的字节序列会包含对象的类型信息、对象的数据等,说白了就是包含了描述这个对象的所有信息,能根据这些信息“复刻”出一个和原来一模一样的对象。
二.为什么
那么为什么要去进行序列化呢?有以下两个原因
- 持久化:对象是存储在JVM中的堆区的,但是如果JVM停止运行了,对象也不存在了。序列化可以将对象转化成字节序列,可以写进硬盘文件中实现持久化。在新开启的JVM中可以读取字节序列进行反序列化成对象。
- 网络传输:网络直接传输数据,但是无法直接传输对象,可在传输前序列化,传输完成后反序列化成对象。所以所有可在网络上传输的对象都必须是可序列化的。
简单来说,磁盘进内存就要反序列化,内存要传输,或者存进磁盘,就要序列化。
三.怎么做
怎么去实现对象的序列化呢?
Java为我们提供了对象序列化的机制,规定了要实现序列化对象的类要满足的条件和实现方法。
- 对于要序列化对象的类要去实现Serializable接口或者Externalizable接口
- 实现方法:JDK提供的ObjectOutputStream和ObjectInputStream来实现序列化和反序列化
四.hadoop中的序列化
hadoop的读写语句分别如下:
JavaPairRDD<BytesWritable,BytesWritable> rdd = javaSparkContext.hadoopFile(path, PBInputFormat.class, BytesWritable.class, BytesWritable.class);
解析:
只是按照PBInputFormat.class的格式对写入的文件,进行拆分,分成<key,value>,并进行反序列化。
即:
1.反序列化 2.解析成BytesWritable对象
点进源码里也可以看到, 实现了Serializable接口。
byte[] originalValue = rdd.map(data -> data._2.getBytes()).
序列化的写入方法同理:
rdd.saveAsHadoopFile(outputPath, BytesWritable.class, BytesWritable.class, PBOutputFormat.class);
常见的OutputFormat实现类
1、TextOutputFormat
默认的输出格式是TextOutputFormat,它把每条记录写在文本行。
它的键和值可以是任意类型,因为TextOutputFormat调用toString()方法可以把他们转换成字符串
2、SequenceFileOutputFormat
将SequenceFileOutputFormat输出作为后续 MapReduce任务的输入,这便是一种好的输出格式。
因为它的格式紧凑,很容易压缩
3、自定义OutputFormat
根据用户需求,自定义实现输出
## 自定义OutputFormat
1、自定义一个继承FileOutputFormat
2、改写RecordWriter,具体改写输出数据的方法write()
PBOutputFormat属于这个