因为在Hadoop和Spark中经常遇到可序列化对象,所以又复习一边Java序列化和反序列化对象
1、Java的序列化和反序列化对象
Java的序列化就是把Java对象转化为字节序列的形式,该字节序列包括该对象的数据、有关对象类型的信息和存储在对象中数据的类型。而反序列化作用就是字节序列恢复为Java对象的过程。
对象序列化的作用: 将对象序列化就是为了存储在文件中(实现数据的持久化,通过序列化可以把数据永久地保存到硬盘上)或者进行网络传输(利用序列化实现远程通信,在网络上传送对象的字节序列)。在网络传输的时候,可以是字节、字符串、XML或者对象(Object)等格式的数据。传字符串的时候,接收方很容易解析出来,但是当你传一个对象的时候,接收方读完字节流后,不知道你传的什么对象,所以接收方没办法给你转成原来的对象并解析对象的属性。这个时候就需要把对象序列化为字节序列,而字节、XML格式的数据可以完全还原完全相等的对象,这就是反序列化的过程。
现在通过代码来实际解释下:
创建了一个Student类:
package ObjectSerializable;
import java.io.Serializable;
//创建了一个Student类,然后定义了一些基本属性。
//Java中如果一个类要实现序列化,有两种方式,实现Serializable或者Externalizable接口,否则跑出异常。
public class Student implements Serializable {
private String name;
private char sex;
private int age;
private double score;
public Student(String name, int age, char sex, double score){
this.name = name;
this.age = age;
this.sex = sex;
this.score = score;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return this.age;
}
public void setSex(char sex){
this.sex = sex;
}
public char getSex(){
return this.sex;
}
public void setScore(double score){
this.score = score;
}
public double getScore(){
return this.score;
}
}
把Student类的对象序列化到文件指定目录的文件中,并从该文件中反序列化,同时打印结果。代码如下:
package ObjectSerializable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import ObjectSerializable.Student;
public class ObjectDeserialize {
public static void main(String[] args){
Student st = new Student("Hugh", 26, '男', 99.88);
//当执行这里时,在内存的栈空间存在一个file的引用,在堆空间里存在一个student.txt对象
//注意这个对象只含有文件的属性(如大小,是否可读,修改时间等),不包含文件的内容,所以length=0。当我们想执行对文件的操作的时候,这个时
//候抽象路径起作用了,比如我们想执行file.createNewFile()命令时,虚拟机会将抽象路径转化为实际的物理路径,到这个转化后的物理路径(此时
//是硬盘)下进行文件的创建。
File file = new File("G:\\eclipseworkspace\\student.txt");
try{
file.createNewFile();
}
catch(IOException e){
e.printStackTrace();
}
try{
//student对象序列化过程
//new FileOutputStream(file) 向file指向的文件中写入数据的文件输出流
FileOutputStream fs = new FileOutputStream(file);
//对象序列化时,需创建ObjectOutputStream输出流,这是一个处理流,必须建立在其他节点流的基础上
ObjectOutputStream os = new ObjectOutputStream(fs);
//调用writeObject方法输出可序列化对象,将st对象写入输出流
os.writeObject(st);
//flush是把缓冲区的数据强行输出
//主要用在IO中,即清空缓冲区数据,一般在读写流(stream)的时候,数据是先被读到了内存中
//再把数据写到文件中,当你数据读完的时候不代表你的数据已经写完了,因为还有一部分有可能会留在内存这个缓冲区中
//这时候如果你调用了close()方法关闭了读写流,那么这部分数据就会丢失,所以应该在关闭读写流之前先flush()。
os.flush();
os.close();
fs.close();
//student对象序列化过程
FileInputStream fs2 = new FileInputStream(file);
ObjectInputStream os2 = new ObjectInputStream(fs2);
Student st1 = (Student) os2.readObject();
System.out.println("name="+ st1.getName());
System.out.println("age="+ st1.getAge());
System.out.println("sex="+ st1.getSex());
System.out.println("score="+ st1.getScore());
os2.close();
fs2.close();
}
catch(ClassNotFoundException e){
e.printStackTrace();
}
catch (IOException e){
e.printStackTrace();
}
}
}
结果如下:
name=Hugh
age=26
sex=男
score=99.88
参考链接:
http://blog.csdn.net/wangloveall/article/details/7992448
http://blog.sina.com.cn/s/blog_9386f17b0100w2vv.html