序列化与反序列化技术

持久化技术

将内存中的临时数据,保存到本地硬盘的技术;持久化之后,即使程序重启,也不会造成数据的丢失和重置

使用常规的方法将数据存取在文件中

将集合中的数据写入文件

//创建student集合
List<Student> stus = new ArrayList<Student>();
stus.add(new Student(1,"小马",16));
stus.add(new Student(2,"小菜",16));
stus.add(new Student(3,"小希",18));
//将集合中的数据写入文件
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File("路径"))));
//向文件中写数据
for(Student stu : stus){
    bw.write(stu.getId());
    bw.write(stu.getName());
    bw.write(stu.getAge());
    bw.newLine();
    bw.fulsh();
}
/*
查看文件的时候,会发现出了字符串,其他都是乱码,可以使用+""转成字符串
bw.write(stu.getId()+",");//转成字符串
bw.write(stu.getName()+",");
bw.write(stu.getAge()+"");
*/
bw.close();

将文件中的数据存入集合之中

//创建集合存放学生数据
List<Student> stus = new ArrayList<Student>();
//读取学生的数据
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("路径"))));
//存放读出来的每条字符串的数据
String strStu;
while((strStu=br.readLine())!=null){
    //文本中每一行的字符串
    //1,小马,16
    //2,小菜,16
    //3,小希,18
    //将字符串按照“,”分割,每个字符串会被分成一个字符串数组
    String[] strs = strStu.split(",");
    //创建学生对象,获取数据
    Student stu = new Student();
    //strs是第一行字符串以逗号分开的字符串数组,将值对象的传给stu的每    个属性
    stu.setId(Integer.parseInt(strs[0]));
    stu.setName(strsp[1]);
    stu.setAge(integer.parseInt(strs[2]));
    //输出学生对象
    System.out.println(stu);
    //学生对象存入集合之中
    stus.add(stu);
}
br.close();

使用序列化技术,进行持久化

使用对象的序列化技术,来进行持久化。简化数据转换的操作,直接将对象的序列化之后存入文档,取出时进行反序列化可直接取出对象,而不用再进行繁琐的字符串操作

  • 序列化:

    将对象转换成方便传输的流(输出)

    • 使用ObjectOutputStream流中的writeObject(obj)的方法,将Obj对象序列化到流中
  • 反序列化:

    将流转换成对应的对象(输入)

    • 使用ObjectInputStream流中的readObject()方法,将流中的对象反序列化为对象
  • 注意:

    需要传输的对象对应的实体类必须实现序列化接口implements Serializable

    • Serializable接口中没有任何属性和方法,仅仅是一个标志,标志着它的实现类可以被序列化而已

序列化,将对象序列化,写入文件

//创建一个对象
Student stu = new Studet(1,"小马",13);
//使用最基础的字节流创建序列化对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("路径")));
//oos.writeObject(stu);
oos.close();
//此时文件中存储的内容任然是乱码,但是程序反序列化时可以识别这些数据,将这些数据完整的转换成原来的对象

反序列化,文件中的内容取出来反序列化成对象

//创建读取的反序列化对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("路径")))
//readObject方法返回的是一个对象
Student getStu = (Student)ois.readObjet();
//反序列化取出的可以取出对象,替代了繁琐的数据转换的操作,直接一步到位,读取出来就是一个对象

序列化ID

serialVersionUID,作为唯一标识,一般实现是程序化接口时,会把这个作为常量加入到实体类中,用来判断这个类的对象没有被修改过,防止程序修改了对象数据造成文件和程序对象数据不一致

反序列化一次读取多个对象

1.创建自定义类

创建自定义类,继承ObjectOutputStream类,重写里面的writeStreamHeader()方法

/**
 *  使用序列化写入对象时,如果是第一次写入文件(文件为空)
 *  就用objectOutputStream写对象,会写入一个头标记
 *  如果不是第一次,就用自定义类写对象,就不会写入头标记
 */
//自定义一个类叫SubObjOutputStream,继承ObjectOutputStream
public class SubObjOutputStream extends ObjectOutputStream{
    //调用父类的构造方法
    public SubObjOutputStream(OutputStream out) throws IoException{
        super(out);
    }
    //重写父类中的写头标记的方法
    //每次调用writeObject写入对象时都会先调用此方法,安子文就按中写入头标记
    //但是一个文件中只需要一个头标记即可,文件你中有多个头标记会报异常
    @Override
    protected void writeStreamHeader() throws IOException{
        //注释掉,不让他写头标记
        //super.writeStreamHeader();        
    }
}

2.序列化对象

public class Demo01{
    public static void main(String[] args)throws Exception{
        FileOutputStream fos = new FileOutputStream("test.txt",true);//字节流,true代表可以追加写入
        //声明一个序列化对象
        ObjectOutputStream oos = null;
        //先获取路径文件的test.txt
        File f = new File("test.txt");
        //如果文件的长度小于1,代表这个文件是空的,第一次写入文件
        if(f.length()<1){
            //使用ObjectOutputStream来序列化对象
            oos = new ObjectOutputStream(fos);
        }else{
            //如果里面有对象,就是用SubObjOutputStream来序列化对象
            //使用SubObjOutputStream序列化对象,不会待遇头标记
            oos = new SubObjOutputStream(fos);
        }

        User user = new User(3,"小希",18);
        //将对象存入
        oos.writeObject(user);
        //关流
        oos.close();
    }
}    

3.反序列化读取多个对象

public class Demo02{
    //反序列化
    public static void main(String[] args)throws Exception{
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("路径"));

        //单条输出输出
        User u1 = (user)ois.readObject();
        USer u2 = (user)ois.readObject();
        //取消多余头标记后可以正常输出两个对象
        System.out.println(u1);
        System.out.println(u2);

        /**
        *    反序列化时,如果只有两条数据反序列化,读取次数超过2次的话就会异常
        *     如何依次输出说有的对象
        *     要使用异常捕获,一旦读取完毕就给提示
        */
        try{
            Object obj = null;
            while((obj=ois.readObject())!=null){
                User user = (User)obj;
                System.out.println(user);
            }catch(EOFException e){
                System.out.println("读取完毕");
            }
        }
        ois.close();
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值