• 【Java】文件操作篇(四)序列化与对象处理流


    💁 个人主页:黄小黄的博客主页
    ❤️ 支持我:👍 点赞 🌷 收藏 🤘关注
    🎏 格言:All miracles start from sometime somewhere, make it right now.
    本文来自专栏:JavaSE从入门到精通
    在这里插入图片描述


    1 序列化与反序列化

    1. 序列化就是在保存数据时,保存数据的值和数据类型;
    2. 反序列化就是在恢复数据时,恢复数据的值和数据类型;
    3. 需要让某个对象支持序列化机制,则必须让其类是可序列化的;
    4. 为了让某个类是可序列化的,该类必须实现 SerilizableExternalizable 两个接口之一。

    为什么需要对象处理流?

    答:假设我们存储了 int num = 20这个数据到文件中,而这个20是一个数字,我们需要从文件中将数据恢复。
    可是,文件中仅仅存储了 20 这一个数字,我们没有办法判断,存储它的时候是将它存储为了 int 类型还是 String 类型。
    而对象处理流,就是帮助我们解决类似问题的,即:能够将 基本数据类型 或者 对象 进行序列化和反序列化操作!


    2 对象处理流

    2.1 概述

    • ObjectOutputStream 提供 序列化功能;
    • ObjectInputStream 提供 反序列化功能。
    • 提供了对基本类型或者对象类型的序列化和反序列化方法。

    类的继承关系图如下:
    在这里插入图片描述

    2.2 ObjectOutputStream案例

    使用ObjectOutputStream序列化基本数据类型和一个Student对象(name,age),保存到data.dat文件中。

    ⌨️ 参考代码与结果:

    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    
    /**
     * @author 兴趣使然黄小黄
     * @version 1.0
     * 序列化基本数据类型和对象类型演示
     */
    public class ObjectOutputStreamTest {
        public static void main(String[] args) {
            //创建流对象
            ObjectOutputStream objectOutputStream = null;
            try {
                objectOutputStream = new ObjectOutputStream(new FileOutputStream(
                        "D:\\Ideaproject2021\\JavaSE\\src\\IOchapter\\data.dat"));
                //序列化后,保存的文件格式,不是纯文本,而是按照它自己的格式存储的
                //序列化数据
                //int -> Integer(实现了 Serializable)
                objectOutputStream.writeInt(100);
                //boolean -> Boolean(实现了 Serializable)
                objectOutputStream.writeBoolean(true);
                //char -> Character
                objectOutputStream.writeChar('a');
                //String
                objectOutputStream.writeUTF("黄小黄");
                //保存一个Student对象
                objectOutputStream.writeObject(new Student("黄小黄", 21));
    
                System.out.println("数据序列化成功!");
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                //释放资源
                if(objectOutputStream != null) {
                    try {
                        objectOutputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
    class Student implements Serializable{
        private String name;
        private int age;
    
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    在这里插入图片描述

    🐦 说明:

     序列化基本数据类型的时候,会进行自动装箱。比如存储int类型的100,则会以Integer的形式自动装箱后存储,因为Integer实现了Serializable接口。

    2.3 ObjectInputStream案例

    使用ObjectInputStream读取data.dat的数据,并反序列化恢复数据。

    ⌨️ 参考代码与结果:

    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    
    /**
     * @author 兴趣使然黄小黄
     * @version 1.0
     */
    public class ObjectInputStreamTest {
        public static void main(String[] args) {
            //创建流对象
            ObjectInputStream objectInputStream = null;
            try {
                objectInputStream = new ObjectInputStream(new FileInputStream(
                        "D:\\Ideaproject2021\\JavaSE\\src\\IOchapter\\data.dat"));
                //读取数据
                System.out.println(objectInputStream.readInt());
                System.out.println(objectInputStream.readBoolean());
                System.out.println(objectInputStream.readChar());
                System.out.println(objectInputStream.readUTF());
                System.out.println(objectInputStream.readObject());
                //程序结束
                System.out.println("反序列化完成!");
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } finally {
                //释放资源
                if (objectInputStream != null){
                    try {
                        objectInputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    在这里插入图片描述

    🐱 说明:

    反序列化的顺序一定要与序列化的顺序一样,否则,程序会抛出异常。

    2.4 对象处理流的使用细节

    1. 读写顺序一致,即序列化与反序列化的顺序应该一致;
    2. 要求实现序列化或者反序列化对象,需要实现Serializable接口;
    3. 序列化类中建议添加SerialVersionUID,为了提高版本兼容性;
    4. 序列化对象时,默认将里面所有的属性都进行序列化,但static与transient修饰的成员除外;
    5. 序列化对象时,要求里面的属性的类型也要实现序列化接口;
    6. 序列化具备可继承性,也就是如果某类已经实现了序列化,则它的所有子类也已经默认实现了序列化。

    写在最后

    🌟以上便是本文的全部内容啦,后续内容将会持续免费更新,如果文章对你有所帮助,麻烦动动小手点个赞 + 关注,非常感谢 ❤️ ❤️ ❤️ !
    如果有问题,欢迎私信或者评论区!
    在这里插入图片描述
    共勉:“你间歇性的努力和蒙混过日子,都是对之前努力的清零。”
    在这里插入图片描述

  • 相关阅读:
    docker 安装(unbuntu安装)
    PSS:你距离NMS-free+提点只有两个卷积层 | 2021论文
    Flutter组件--Padding和AnimatedPadding
    中央党校出版社元宇宙图书编委高泽龙在元宇宙100分第24期做分享
    第4章 系统管理员模块功能实现
    【日志技术——Logback日志框架】
    day10_复习_数组_方法
    Keil使用实战总结
    2023年11月IDE流行度最新排名
    3-面试官:说说线程池的 7 大参数
  • 原文地址:https://blog.csdn.net/m0_60353039/article/details/126835386