Java对象流ObjectInputStream和ObjectOutputStream使用

使用前你应该先了解下面的内容

什么是对象流?

        对象流就是通过序列化方式,将数据一段一段的存放在硬盘文件中。

        数据可以包括,基本数据类型和引用数据类型(数组和new出来的对象)

        通过反序列化方式,再将硬盘文件的数据,读入到内存中。

        注意:这里就涉及到了序列化相关知识

如何实现序列化?

        什么是Serializable接口?

                通过对象流传输的数据都要实现Serializable接口,这样就可以将数据序列化到硬盘文件中以及反序列化到内存中。

        基本数据类型的数据都已经实现了Serializable接口

        引用数据类型的对象必须要实现Serializable接口,这是需要我们手动实现这个接口

  例子:               

public class Student implements Serializable{
    // 序列号编号,值随便写,告诉JVM这个类可以进行序列化操作
    private static final long serializableUID = 1L;
    
    .......
}

现在你可以开始学习使用对象流了🤭🤭

ObjectInputStream和ObjectOutputStream的使用

例子:将数据序列化到硬盘文件中

// 将list数据,序列化到硬盘文件中
public String objectStream(List<Student> list) {
    try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream(读取的文件位置))){
        // 硬盘数据反序列化到内存中
        List<Student> origin = ois.readObject();
        // 创建目标集合,序列化到硬盘文件中
        List<Student> target = new ArrayList<>();
        for(Student s : origin) {
            target.add(s);
        }
        // 创建对象输出流,将target序列化到硬盘文件中
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(读取的文件位置));
        oos.wirteObject(target);
        return "list成功序列化";
    }catch(Exception e) {
        e.printStack();
    }finally {
        // 关闭对象输出流
        // 偷个懒
        oos.close();
    }
}

这里解释一下:代码中为什么要创建一个target集合,为什么要先反序列化读入内存中而不直接序列化到硬盘文件中去?

因为我们不能够保证硬盘文件中是否已经存在数据,如果直接将数据序列号到硬盘文件中,里面的内容就会全部覆盖掉,所以创建一个target集合,保存原来的数据,最后将我的新添加的数据,添加到target集合里,再使用对象输出流序列化到硬盘文件中。这样我们的数据就相当于追加到文件内容的最后面。

大爆料🧨🧨🧨继续往下看,很重要!!!

这里我给大家分享一下我刚使用对象流做项目时候遇到的坑,泪目😂😂当时花了3个小时解决掉

对象流使用注意事项

1.当我们需要将数据进行序列化操作时,一定要实现Serializeble接口,并且一定一定要在类中添加一个序列号常量,private static final long serializableUID = 1L;避免项目重新启动时出现无法序列化异常。为什么会出现无法序列化异常呢,可能是你序列化之后,又在类中添加或删除或修改了某个属性才导致序列化冲突。我教你怎么解决,很简单,第一步,把目标文件删掉;第二步,看看类中是否加了序列号常量,如果加了这一步忽略;第三步,项目重启跑起来。

2.ObjectInputStream和ObjectOutputStream不能在一起new,不然会出现java.io.EOFException at java.io.ObjectInputStream$BlockDataInputStream.peekByte异常,看看你是不是放在一起new了。如果遇到这个异常我教你怎么解决。其实我上面的例子已经写过一次了。很简单,就是我们把对象输入流和对象输出流分开写,如何分开呢?就是我们先使用ois.readObject()读入内存之后,再new对象输出流,将数据写到文件中,这样就不会报错。作者我当时就是因为懒,不想手动关闭流使用try-with-resources语法糖(这个语法糖链接下面放),将这两个对象流放在一起new,操操操。

3.出现java.lang.UnsupportedOperationException不支持操作异常,为什么出现这个异常呢,你程序中应该将反序列化的数据进行了add操作,

比如List<Student> list = ois.readObject();list.add(stu);这里是不能添加数据的,怎么解决,我上面例子写了。创建一个target集合,将list拷贝到target集合中。stu添加到target里。再把target序列化

4.一定一定要写序列化,然后再反序列化

5.序列化到硬盘文件中的数据是乱码,这是正常的。

try-with-resources语法糖博客地址:

每日一学--Java语法糖 try-with-resources_菜鸟郭郭的博客-CSDN博客

坚持到这里的朋友,动动下手指点个攒呗👍

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值