• Java序列化流的奇妙之旅


    Java序列化流有何奇妙之处呢?通过一个个案例逐一感受序列化流。

    !!!好戏在后头!!!

    1.IO流读写文件

    先从一个普通文件读写字符串开始讲起。

    例子:输出字符串到文件,再从文件中读取字符串

    image

    在某一天灵感迸发:我可以把Java程序中的对象信息直接保存到普通的 txt 文件中吗?并且当我想使用它时,还可以拿出来就可以直接用,不需要再做其他处理,就像存储普通的字符串一样,在文件中读出来就可以直接使用的那种。

    2.序列化和反序列化流奇妙之处

    要想实现对象信息存储到普通文件不被破化,并且读取出来不需要再做其他处理既可以像使用普通new出来的对象一样直接使用的效果,必须有一种特殊的IO流来完成,于是诞生了序列化流和反序列化流

    2.1.案例一:把普通文件当作对象存储库来使用

    详细的描述:将一个list 集合保存到普通文件,再读出来直接使用,实现list集合数据的增删改查

    Person 类

    // 序列化对象信息:必须实现序列化标记接口Serializable
    public class Person implements Serializable {
        // 序列化版本UID
        private static final long serialVersionUID = 1L;
        private String name;
        private int age;
        private String sex;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        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;
        }

        @Override
        public String toString() {
            return "Person{" + "name='" + name + ", age=" + age + ", sex='" + sex + '}';
        }
        public Person() {
        }
        public Person(String name, Integer age, String sex) {
            this.name = name;
            this.age = age;
            this.sex = sex;
        }
    }

    序列化和反序列化

    public class Demo2 {
        public static void main(String[] args) throws IOException, ClassNotFoundException {
            //数据准备:集合类都实现了序列化接口Serializable
            List<Person> list = new ArrayList<>();
            list.add(new Person("张三",38,"男"));
            list.add(new Person("李四",38,"男"));
            list.add(new Person("如花",18,"女"));

            // 序列化保存到普通文件
            File file = new File("D:/demo2.txt");
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(file));
            objectOutputStream.writeObject(list);
            objectOutputStream.close();

            // 读取普通文件反序列化
            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file));
            List<Person> personList = (List<Person>) objectInputStream.readObject();
            objectInputStream.close();
            for (Person person:personList){
                System.out.println(person);
            }
            
        }
    }

    执行结果:

    image

    序列化保存到普通文件的数据:

    image

    虽然没人会考虑使用这种方式来保存数据,但这对于理解序列化流有很大的帮助。

    2.2.案例二:任意元素类型的List 集合序列化读写

    **
     * 任意元素类型的List 集合的对象存储到普通文件,读取直接使用
     * @param <T>
     */
    public class ObjectList<T extends List> {
        // 序列化保存到普通文件
        private File file = new File("D:/demoList.txt");

        public void writerList(T t) throws IOException {
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(file));
            objectOutputStream.writeObject(t);
            objectOutputStream.close();
        }

        public T readList() throws IOException, ClassNotFoundException {
            // 读取普通文件反序列化
            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file));
            T t = (T) objectInputStream.readObject();
            objectInputStream.close();
            return t;
        }

        public boolean isExists(){
            return file.exists();
        }
        public boolean delete(){
            return file.delete();
        }

        // 测试
        public static void main(String[] args) throws IOException, ClassNotFoundException {
            ObjectList<List<Person>> objectList = new ObjectList<>();
            //数据准备:集合类都实现了序列化接口Serializable
            List<Person> list = new ArrayList<>();
            list.add(new Person("张三",38,"男"));
            list.add(new Person("李四",38,"男"));
            list.add(new Person("如花",18,"女"));
            // 持久化对象数据
            objectList.writerList(list);
            // 查询持久化对象数据
            List<Person> personList = objectList.readList();
            System.out.println("遍历持久化对象数据>");
            for (Person person:personList){
                System.out.println(person);
                if (person.getAge()==38){// 修改年龄38的都改为18
                    person.setAge(18);
                }
            }
            // 修改后持久化对象数据
            objectList.writerList(personList);
            System.out.println("遍历修改持久化对象数据>");
            List<Person> personList1 = objectList.readList();
            for (Person person:personList1){
                System.out.println(person);
            }
            // 删除对象存储的持久化文件
            if (objectList.isExists()){
                System.out.println("删除对象存储的持久化文件");
                objectList.delete();
            }

        }

    }

    序列化的目的

    • 序列化流目的:把对象模型数据按序列化规则进行转化,转化后的数据可以保存到磁盘文本或通过网络传输;
    • 反序列化流目的:把磁盘文件或网络传输的序列化数据按反序列化规则进行转化,恢复成对象模型数据,在程序中可直接操作对象模型数据。

    前面的案例都是程序和磁盘的IO操作,接下来的是序列化对象通过网络传输的案例。

    2.3.案例三:自己实现Java RMI(远程方法调用)

    Java RMI(Remote Method Invocation)Java 远程方法调用,是Java编程语言里的一种用于实现远程方法调用的应用程序编程接口。RMI的宗旨就是尽可能简化远程接口对象的使用。

    相类似的远程过程调用RPC(Remote Procedure Call),指的是一个进程调用另一个进程(本地或远程主机的进程)的过程。Java 的 RMI 则在 RPC 的基础上向前又迈进了一步,既提供了分布式对象间的通讯。但Java RMI仅限于Java语言间相互调用,无法实现不同语言间的远程方法调用。

    在这感受下怎么实现远程方法调用,好玩时刻来了。

    !!!高能预警!!!

    篇幅原因,请移步到:自己写了个Java RMI(远程方法调用) 的实现案例

    image

    image

    Java往期文章

    Java全栈学习路线、学习资源和面试题一条龙

    我心里优秀架构师是怎样的?

    免费下载经典编程书籍

    更多优质文章和资源

    image

    原创不易:分享,点赞

  • 相关阅读:
    Tsar 服务器系统和应用信息的采集报告工具
    mysqltuner
    MySQL性能监控工具-MONyog
    tuning-primer.sh mysql 报表
    mytop
    InnoTop
    mysql监控管理工具--innotop
    iotop,pt-ioprofile : mysql IO负载高的来源定位
    PERCONA-TOOLKIT 工具的安装与使用2
    PERCONA-TOOLKIT : pt-ioprofile分析IO情况
  • 原文地址:https://www.cnblogs.com/dennyLee2025/p/15977942.html
Copyright © 2020-2023  润新知