java 序列化和反序列化
为什么要用序列化
第一种情况是:一般情况下Java对象的声明周期都比Java虚拟机的要短,实际应用中我们希望在JVM停止运行之后能够持久化指定的对象,这时候就需要把对象进行序列化之后保存。
第二种情况是:需要把Java对象通过网络进行传输的时候。因为数据只能够以二进制的形式在网络中进行传输,因此当把对象通过网络发送出去之前需要先序列化成二进制数据,在接收端读到二进制数据之后反序列化成Java对象。
概念:
- 序列化就是将对象的状态写入到特定流中的过程==将数据写入文本
- 反序列化就是从特定的流中获取数据重新构建对象的过程
实现:
Serializable 接口
ObjectInputStream 类
ObjectOutputStream 类
废话少说,直接上案例
我有一个学生类,有一个测试类(含主方法),
我创建5个学生对象,想把这个对象数组保存起来,以便下次使用或传输
- 学生类: 需要实现Serializable 接口 为了可以实现序列化
import java.io.Serializable;
public class Student implements Serializable{
private int nid;
private String name;
public Student(int nid, String name) {
//super();
this.nid = nid;
this.name = name;
}
@Override
public String toString() {
return "Student [nid=" + nid + ", name=" + name + "]";
}
}
- 新建一个序列类,里面两个方法,一个是把对象序列化,另一个测试反序列化
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class Sequences {
/**
* 方法一 把学生对象 序列化
* @param f
* @param s
*/
// 需要传入一个存储序列化的文件(确保文件已经存在),另一个参数是要序列化的对象数组
public void showXuStu(File f,Student[] s) {
FileOutputStream fos = null; //创建读取流,写入数据
try {
if(fos == null){
//fos = new FileOutputStream(f,true);
fos = new FileOutputStream(f);
}
//将Java对象的原始数据类型和图形写入OutputStream
ObjectOutputStream oos = new ObjectOutputStream(fos);
// 遍历学生对象数组
for (Student stu:s) {
oos.writeObject(stu); //写入
}
oos.writeObject(null); //如果不写,可能会报异常IOException - 如果在写入流标题时发生I / O错误
System.out.println("写入成功!");
oos.flush(); //刷新一下
if(oos!=null)
oos.close();
}catch(Exception e) {
e.printStackTrace();
}finally {
if(fos!=null)
try {
fos.close(); //关闭流
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 学生对象的反序列化
*/
public void showXuStuIn(File f) {
FileInputStream fis = null; //创建读取流
try {
if(fis == null)
fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis); //从流中读取对象
Student obj = (Student)ois.readObject(); //强转成学生对象
while(obj != null) {
System.out.println(obj.toString()); //输出对象
obj = (Student)ois.readObject(); //读取下一个
}
if(ois!=null)
ois.close();
if(fis!=null)
fis.close();
}catch(Exception e) {
e.printStackTrace();
}
}
}
分析上面的的代码,在序列化的方法中,核心代码一共就这么几句;
其中的try catch是用流必须带的,循环和提示语言看情况而定
FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(stu);
oos.flush();
oos.close();
fos.close();
- 测试类
import java.io.File;
import java.io.IOException;
public class Work1 {
public static void main(String[] args) {
File f = new File("e:/demo01.txt");
// 如果文件不存在则 创建文件
if (!f.exists()) {
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
Sequences s = new Sequences();
Student[] sd = {
new Student(1,"a"),
new Student(2,"b"),
new Student(3,"c"),
new Student(4,"d"),
new Student(5,"e")
};
s.showXuStu(f, sd); //序列化
s.showXuStuIn(f); //反序列化
}
}
结果: