Java IO流--对象流ObjectInputStream和ObjectOutputStream及对象序列化机制的理解

简介: Java IO流--对象流ObjectInputStream和ObjectOutputStream及对象序列化机制的理解

对象序列化机制:

允许把内存中的java对象转换成平台无关的二进制流,从而允许把这种二进制流永久的保存到磁盘上,或通过网络将这种二进制流传输到另一个网络节点。(序列化)

当其他程序获取了这种二进制流,就可以恢复成原来的java对象。(反序列化)

序列化的理解:

  1. 序列化就是在保存数据时,保存数据的值和数据类型。
  2. 用ObjectOutputStream类保存基本数据类型或对象的机制。
  3. ObjectOutputStream提供了序列化的功能。

反序列化的理解:

  1. 反序列化就是在恢复数据时,恢复数据的值和数据类型。
  2. 用ObjectInputStream类读取基本数据类型或对象的机制。
  3. ObjectInputStream提供反序列化的功能。

一、对象流的使用一:ObjectOutputStream和ObjectInputStream

1.使用ObjectOutputStream进行序列化操作,具体代码如下:

/**
 * 演示ObjectOutputStream的使用,完成数据的序列化
 */
public class ObjectOutputStream_ {
    public static void main(String[] args) {
        //序列化后,保存的文件格式,不是存文本,而是按照它的格式来保存
        String filePath = "D:\\data.dat";
        ObjectOutputStream objectOutputStream = null;
        try {
            objectOutputStream = new ObjectOutputStream(new FileOutputStream(filePath));
            //序列化数据到D:\\data.dat
            objectOutputStream.writeInt(100); //int ->Integer(实现了Serializable接口)
            objectOutputStream.writeBoolean(true); //boolean->Boolean(实现了Serializable接口)
            objectOutputStream.writeDouble(90.5); //double->Double(实现了Serializable接口)
            objectOutputStream.writeUTF("筱路");
            //保存一个Dog对象
            objectOutputStream.writeObject(new Dog("小黄", 3));
            System.out.println("数据保存完毕(序列化形式)");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (objectOutputStream != null) {
                    objectOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

2.使用ObjectInputStream进行反序列化操作,具体代码如下:

public class ObjectInputStream_ {
    public static void main(String[] args) {
        //指定反序列化的文件
        String filePath = "D:\\data.dat";
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream(filePath));
            //读取
            //1.读取(序列化)的顺序需要和你保存(序列化)的顺序一致
            //2.否则会出异常
            System.out.println(ois.readInt());
            System.out.println(ois.readBoolean());
            System.out.println(ois.readDouble());
            System.out.println(ois.readUTF());
            //dog的编译类型是Object,dog的运行类型是Dog
            Object dog = ois.readObject();
            System.out.println("运行类型=" + dog.getClass());
            System.out.println("dog信息=" + dog);
            //注意细节
            //1.如果我们希望调用Dog的方法,需要向下转型
            //2.需要我们将Dog类的定义,放在可以引用的位置
            Dog dog2 = (Dog) dog;
            System.out.println(dog2.getName());
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if (ois != null) {//关闭流,关闭外层流即可,底层会关闭FileInputStream流
                    ois.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

具体日志输出信息为:

100
true
90.5
筱路
运行类型=class file.outputStream_.Dog
dog信息=Dog{name='小黄', age=3}
小黄

二、对象流的使用二:ObjectOutputStream和ObjectInputStream

/**
     * 序列化过程:将内存中的java对象保存到磁盘中或通过网络传输出去
     * 使用ObjectOutputStream实现
     */
 @Test
    public void test1(){
        ObjectOutputStream oos = null;
        try {
            //造文件和处理流
            oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
            //把数据写出到磁盘中
            oos.writeObject("程序员");
            oos.flush();//刷新操作
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (oos!=null){
                //关闭资源
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
  /**
     * 反序列化过程:将磁盘文件中的对象还原为内存中的一个java对象
     * 使用ObjectInputStream实现
     */
    @Test
    public void test2(){
        ObjectInputStream ois=null;
        try {
            //造文件和对象流
            ois = new ObjectInputStream(new FileInputStream("object.dat"));
            //把数据读入到内存中
            Object oj = ois.readObject();
            String s = (String) oj;
            System.out.println(s);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
           if (ois!=null){
               try {
                   ois.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
        }
    }


目录
相关文章
|
人工智能 Java 关系型数据库
Java——SPI机制详解
SPI(Service Provider Interface)是JDK内置的服务提供发现机制,主要用于框架扩展和组件替换。通过在`META-INF/services/`目录下定义接口实现类文件,Java程序可利用`ServiceLoader`动态加载服务实现。SPI核心思想是解耦,允许不同厂商为同一接口提供多种实现,如`java.sql.Driver`的MySQL与PostgreSQL实现。然而,SPI存在缺陷:需遍历所有实现并实例化,可能造成资源浪费;获取实现类方式不够灵活;多线程使用时存在安全问题。尽管如此,SPI仍是Java生态系统中实现插件化和模块化设计的重要工具。
758 0
|
10月前
|
存储 NoSQL Java
配置RedisTemplate序列化机制
通过上述步骤,你可以灵活配置RedisTemplate的序列化机制,根据应用需求选择合适的序列化器,从而确保数据在Redis中的存储和读取效率最优化。配置合适的序列化机制对于性能和存储效率至关重要,而且这样可以确保数据在存储和传输过程中的结构清晰和一致性。
591 11
|
9月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
429 1
|
9月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
395 1
|
人工智能 前端开发 安全
Java开发不可不知的秘密:类加载器实现机制
类加载器是Java中负责动态加载类到JVM的组件,理解其工作原理对开发复杂应用至关重要。本文详解类加载过程、双亲委派模型及常见类加载器,并介绍自定义类加载器的实现与应用场景。
405 4
|
JSON Java 数据库连接
|
12月前
|
存储 安全 Java
深入理解Java序列化接口及其实现机制
记住,序列化不仅仅是把对象状态保存下来那么简单,它涉及到类的版本控制、安全性和性能等多个重要方面。正确理解和实现Java序列化机制对于构建高效、安全和可维护的Java应用至关重要。
346 0
|
人工智能 JavaScript Java
Java反射机制及原理
本文介绍了Java反射机制的基本概念、使用方法及其原理。反射在实际项目中比代理更常用,掌握它可以提升编程能力并理解框架设计原理。文章详细讲解了获取Class对象的四种方式:对象.getClass()、类.class、Class.forName()和类加载器.loadClass(),并分析了Class.forName()与ClassLoader的区别。此外,还探讨了通过Class对象进行实例化、获取方法和字段等操作的具体实现。最后从JVM类加载机制角度解析了Class对象的本质及其与类和实例的关系,帮助读者深入理解Java反射的工作原理。
334 0
|
存储 Java 编译器
说一说关于序列化/反序列化中的细节问题
我是小假 期待与你的下一次相遇 ~
261 1
|
存储 安全 IDE
说一说序列化与反序列化中存在的问题
本文详细解析了Java中的序列化机制,包括序列化的概念、实现方式及应用场景。通过Student类的实例演示了对象的序列化与反序列化过程,并分析了`Serializable`接口的作用以及`serialVersionUID`的重要意义。此外,文章还探讨了如何通过自定义`readObject()`方法增强序列化的安全性,以及解决可序列化单例模式中可能产生的多实例问题。最后提供了代码示例和运行结果,帮助读者深入理解序列化的原理与实践技巧。
342 3