• [九]JavaIO之ObjectInputStream 和 ObjectOutputStream



    序列化

    序列化是指把Java对象保存为二进制字节码的过程,Java反序列化是指把二进制码重新转换成Java对象的过程
    序列化是一种轻量级的持久化,对象都是存活在内存中的,当JVM运行结束,对象便不存在了
    如果想要对象还能够存在,或者说当你在网络中想要进行对象数据的传输的话,就需要进行序列化
    说白了就是内存中的数据你要把他变成字节

    ObjectInputStream 和 ObjectOutputStream就是java原生的用于处理序列化的功能

    image_5b985d72_5a7c
    image_5b985d72_19ca


    ObjectStreamConstants 写入 Object Serialization Stream 的常量
    比如http请求似的,会有很多附加信息请求头,class文件有他的文件信息类似的道理
    序列化也会写入一些除了直接数据信息以外的格式等相关的信息
    这部分常量的值就在这个接口中
    DataInput 接口用于从二进制流中读取字节,并根据所有 Java 基本类型数据进行重构
    ObjectInput
    DataInput 包括基本类型的输入方法
    扩展了DataInput接口,以包含对象、数组和 String 
    DataOutput
    接口用于将数据从任意 Java 基本类型转换为一系列字节,并将这些字节写入二进制流
    ObjectOutput
    DataOutput 包括基本类型的输出方法;
    扩展了DataOutput接口,以包含对象、数组和 String 

    从上面的类层次结构以及其他辅助类的说明上可以看得出来
    ObjectStreamConstants 约定了所有序列化时用到的常量信息
    DataInput以及ObjectInput 都是接口,约定了从二进制读取基本类型 对象 数组 String的方法
    DataOutput以及 ObjectOutput也都是接口,约定了将基本类型数据 对象  数组 String  转换为字节写入二进制流的方法
    ObjectInputStream 和 ObjectOutputStream 相当于继承了两个体系
    一个体系是IO的读写方法约定
    另一个是从二进制读取为数据或者数据编写二进制

    两个体系结构的实现,构成了现在的ObjectInputStream 和 ObjectOutputStream
    从下图看得出来
    除了标记的以外,其中绝大多数方法都来自于DataInput     DataOutput
    image_5b985d72_6cd4


    可以看一下关于DataInputStream以及DataOutputStream的介绍
    其实完全可以看得出来,DataInputStream以及DataOutputStream他们两个也算是序列化
    只不过他们不支持对象  数组 String 仅仅支持基本类型,功能不够强大,使用也不够方便
    java原生的序列化不就是  基本类型/对象/数组/String  与 二进制字节流的相互转换嘛


    ObjectInputStream

    ObjectInputStream中的方法大多依赖于bin变量.
    image_5b985d72_4f8a
    比如:
    image_5b985d72_27db
    构造方法中会创建 bin
    image_5b985d72_21be

    bin 他是DataInputStream的内部类 BlockDataInputStream
    BlockDataInputStream内部还有两个变量分别是
    DataInputStream 和PeekInputStream
    image_5b985d72_5f03
    其中的PeekInputStream也是内部类
    image_5b985d72_4c19
    输入流有两种模式:
    在默认模式下,输入数据以与DataOutputStream相同的格式写入;
    在“块数据”模式中,输入数据由块数据标记括起来(详细信息见对象序列化规范)。
    缓冲依赖于块数据模式:在默认模式下,没有预先缓冲任何数据;当在块数据模式下,当前数据块的所有数据都立即读取(并缓冲)
    标记位是DataBlockInputStream中的blkmode

    image_5b985d72_6513
    在BlockDataInputStream中的方法,会根据这个标志位调用不同的方法
    比如
    image_5b985d72_4ca5
    总结:
    ObjectInputStream中的方法很多调用BlockDataInputStream
    BlockDataInputStream又会根据模式blkmode 的值去调用实际的方法

    可能是BlockDataInputStream自己实现的方法
    也可能是PeekInputStream实现的方法


    ObjectOutputStream

    ObjectOutputStream的整体思路其实也是类似于ObjectInputStream的
    它内部也有一个跟BlockDataInputStream  对应的BlockDataOutputStream
    不再详细介绍



    总结

    ObjectInputStream 和 ObjectOutputStream 是java原生的序列化以及反序列化类
    算是DataInputStream和DataOutputStream的超集(功能上的超集,不是父类)
    DataXXX只能处理基本类型,ObjectXXX可以处理 基本类型以及对象 数组 String

    DataInput/ObjectInput
    DataOutput/ObjectOutput
    这四个接口定义了序列化的协议,各种方法的定义
    ObjectInputStream 和 ObjectOutputStream  遵循了IO InputStream 和 OutputStream的约定,提供IO的读写方式
    并且遵守了DataOutput/ObjectOutput的约定,提供了更多的可以用于 数据与二进制字节转换的读写方法
    实际开发使用时只需要关注可以使用的方法即可

    ObjectInputStream 和 ObjectOutputStream可以理解为实现了序列化的功能的一个工具
    所以你必须依托于InputStream 或者OutputStream
    通常是和FileInputStream 和 FileOutputStream配合进行使用的
    看一下他们的构造方法你就知道了 
    image_5b985f69_7613

    image_5b985f69_6b20

  • 相关阅读:
    RFID基础知识
    iOS开发技巧:使用ObjectiveC创建UUID的代码
    Java获取当前路径
    Oracle 10g 一些事项
    windows 2003 下IIS没有ASP.NET 1.1.4322选项卡
    Windows下手动完全卸载Oracle
    C#如何检测网络端口连接的状态
    windows 2003 下oracle从10.2.0.1升级到10.2.0.4
    Oracle 获取当前日期及日期格式
    Retrieving COM for CLSID {0002450000000000C000000000000046} 80040154.
  • 原文地址:https://www.cnblogs.com/noteless/p/9632760.html
Copyright © 2020-2023  润新知