序列化和反序列化的详解
序列化: 就是把内存中的对象,转换成字节序列(或其他数据传输协议)以便于存储(持久化)和网络传输;
反序列化: 就是将收到字节序列(或其他数据传输协议)或者是硬盘的持久化数据,转换成内存中的对象。
像数据库驱动类,就不能序列化,因为序列化后,localhost找不到地址,不能进行反序列化。
1、Java 序列化
是一个重量级序列化框架(Serializable),它会把这个对象的方方面面的信息都序列化出去,产生的二进制序列体积臃肿庞大,但是信息很全。
public class SerDeDemo {
public static void main(String[] args) throws Exception {
Person p = new Person("周洋舟", 288899998.8, 18);
// jdk中自带的序列化工具,它会把这个对象的方方面面的信息都序列化出去,产生的二进制序列体积臃肿庞大,但是信息很全
/*ObjectOutputStream objout = new ObjectOutputStream(new FileOutputStream("d:/p.obj"));
objout.writeObject(p);
objout.close();*/
DataOutputStream dataout = new DataOutputStream(new FileOutputStream("d:/p2.obj"));
dataout.writeUTF(p.getName());
dataout.writeDouble(p.getSalary());
dataout.writeInt(p.getAge());
DataOutputStream dataout2 = new DataOutputStream(new FileOutputStream("d:/p3.obj"));
dataout2.writeInt(18);
dataout2.writeUTF("18");
}
}
2、hadoop序列化
hadoop 自己开发了一套序列化机制(Writable),精简、高效,需要实现write方法 和 readFields方法。
public class Person2 implements Writable {
private String name;
private Double salary;
private int age;
public Person2() {
}
public Person2(String name, Double salary, int age) {
this.name = name;
this.salary = salary;
this.age = age;
}
public void write(DataOutput dataOutput) throws IOException {
dataOutput.writeUTF(this.name);
dataOutput.writeDouble(this.salary);
//dataOutput.writeInt(this.age);
}
public void readFields(DataInput dataInput) throws IOException {
this.name = dataInput.readUTF();
this.salary = dataInput.readDouble();
//this.age = dataInput.readInt();
}
}
3、spark序列化
spark中将对象序列化,默认调用jdk的objectoutputstream(serializable),所以,我们在spark代码中,一般都要修改序列化器,可以用kryo序列化框架,kryo序列化框架的序列化结果要比jdk的序列化结果更精简(少了一些类的元信息)。
object SparkSerde {
def main(args: Array[String]): Unit = {
val spark1 = SparkSession.builder.config("spark.serializer", classOf[KryoSerializer].getName).appName("").master("local").getOrCreate
import spark1.implicits._
spark1.createDataset(Seq(new Person("zz", 1888.8, 28)));
// 上面的做法,kryo在序列化时,还是会带上一些必要的类元信息,以便于下游task能正确反序列化
// 下面的做法,可以提前将这些可能要被序列化的类型,注册到kryo的映射表中,这样,kryo在序列化时就不需要序列化类元信息了
val conf = new SparkConf
conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
conf.registerKryoClasses(Array(classOf[Person],classOf[Person2]))
val spark2 = SparkSession.builder()
.config(conf)
.master("local")
.appName("序列化案例")
.getOrCreate()
}
}
更多java、大数据学习面试资料,请扫码关注我的公众号:

专注于大数据和java开发,学习交流可以关注我的公众号:javaydsj

浙公网安备 33010602011771号