Java IO流学习—序列化与反序列化

1、序列化与反序列化是什么

序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。在IO流中,序列化就是将对象的状态写入到特定的流中的过程,如:将Java对象序列化为二进制的字节序列。
反序列化就是序列化的反过来的过程。

2、序列化和反序列化中使用到IO流的类

1)序列化IO流(ObjectOutputStream)

序列化是将对象转换为流的过程,应该对应的就是输出流,使用的是ObjectOutputStream类

链接: ObjectOutputStream帮助文档.
ObjectOutputStream的构造方法有两个一个是无参的构造方法,一个是带有OutputStream类型的参数:
在这里插入图片描述
ObjectOutputStream类的方法倒是挺多的,特别是带有write的方法挺多的。提供了多种写入文件中的方法,但是现在主要使用的就是带有把对象转换为二进制的字节序列的writeObject():
在这里插入图片描述
在这里插入图片描述

2)反序列化IO流(ObjectInputStream)

反序列化就是将文件中的二进制序列化转换为对象,使用的是ObjectInputStream类

链接: ObjectInputStream帮助文档.
ObjectInputStream类和ObjectOutputStream类差不多,也是只有两个构造方法,一个无参的,一个带InputStream类型参数的构造方法:
在这里插入图片描述
ObjectInputStream类的方法也和ObjectOutputStream类差不多,特别是带read的方法特别多,大家根据不同的情况调用就行了,这里需要注意的是readObject(),这个方法会帮我们把二进制字节序列化转换为对象:
在这里插入图片描述
在这里插入图片描述

3、对象的序列化条件

1)被用于序列化的对象必须实现Serializable 接口

在这里插入图片描述

2、要防止属性被反序列化,导致出现泄密的情况,可以在属性的类型前添加transient关键字,从二进制字节序列化中反序列化出来的对象获取这个属性的时候是一个null,保护了想要保护的值。

在这里插入图片描述

4、例子

1)创建一个个人的属性类,这个类实现Serializable 接口,并且给里面的pwd属性添加transient关键字,防止这个属性被反序列化出来

package com.company;

import java.io.Serializable;

public class Personal implements Serializable {
    private String  name;
    private String ID;
    private transient String pwd;
    private int age;
    private String sex;
    public Personal(){}

    public Personal(String  name,String ID,String pwd,int age,String sex){
        this.name=name;
        this.ID=ID;
        this.pwd=pwd;
        this.age=age;
        this.sex=sex;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getID() {
        return ID;
    }

    public void setID(String ID) {
        this.ID = ID;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}

2)实例化Personal这个类并将这个对象通过ObjectOutputStream转换为二进制字节流存到“E:/zwy/zwy/01.txt”中。

分析:ObjectOutputStream的参数为OutputStream类型,所以需要使用FileOutputStream和ObjectOutputStream两个类。

package com.company;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class SerializableDemo {
    public static void main(String[] args){
        Personal personal=new Personal("小明","0001","123456",18,"男");

        FileOutputStream fos=null;
        ObjectOutputStream oos=null;

        try {
            fos=new FileOutputStream("E:/zwy/zwy/01.txt");
            oos=new ObjectOutputStream(fos);

            oos.writeObject(personal);
            oos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                oos.close();
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

二进制字节显示乱码属于正常的情况
在这里插入图片描述

3)从“E:/zwy/zwy/01.txt”中取出二进制字节流,并通过反序列化得到Personal对象,并打印Personal中的信息到控制台上。

分析:从文件中获取到对象使用ObjectInputStream类,ObjectInputStream类的构造参数是InputStream类型的,也要用到FileInputStream类

package com.company;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

public class DeserializableDemo {
    public static void main(String[] args){
        Personal personal=null;

        FileInputStream fis =null;
        ObjectInputStream ois=null;

        try {
            fis=new FileInputStream("E:/zwy/zwy/01.txt");
            ois=new ObjectInputStream(fis);
            personal=(Personal)ois.readObject();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            try {
                ois.close();
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        System.out.println("name:"+personal.getName());
        System.out.println("ID:"+personal.getID());
        System.out.println("pwd:"+personal.getPwd());
        System.out.println("age:"+personal.getAge());
        System.out.println("sex:"+personal.getSex());
    }
}

pwd属性因为添加了transient关键字,所以反序列化出来的对象中的pwd只得到null
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

szzyjsxyzwy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值