- 对象流
- 序列化(Object)
- 目的:
- 保存(持久化)
- 对象类型, 数据类型, 变量值
- 传输(网络 / 进程通信(有冗余))
- 保存(持久化)
- 目的:
- 反序列化
- 序列化:把对象保存到文件中,可以称为对象序列化到文件
- 反序列化:把对象从文件中读取到程序中,重新组装成对象,可以称为对象的反序
- 序列化(Object)
列化。
- 步骤:
- 被序列化对象类
- 实现java.io.Serializable(标记接口(Cloneable也是标记接口))
- public static final long serialVersionUID = 版本号L
- 实例化文件输入输出流
- 实例化对象输入输出流
- 操作:
- 序列化 -> ObjectOutputStream -> writeObjct()
- 反序列化 -> ObjectInputStream -> Object readObject()
- 关闭流
- 被序列化对象类
- UID/dont save 常量呢?
- transient的用途(面试):
- Q:transient关键字能实现什么?
- A:当对象被序列化时(写入字节序列到目标文件)时,transient阻止实例中那些用此关键字声明的变量持久化;当对象被反序列化时(从源文件读取字节序列进行重构),这样的实例变量值不会被持久化和恢复。
- 例如,当反序列化对象——数据流(例如,文件)可能不存在时,原因是你的对象中存在类型为java.io.InputStream的变量,序列化时这些变量引用的输入流无法被打开。
- 注意:
- 序列化的对象与之后反序列化的对象不是同一个(地址不同)
- 对象的反序列化操作,只能读取一次,同一个文件要写入多个对象,使用对象数组封装后写入
- 同一个文件不要出现多个不同类型的对象。
- 如何序列化
- 在序列化操作中,同时序列化多个对象时,反序列化也必须按顺序操作,如果想要序列化一组对象该如何操作 呢? 序列化一组对象可采用:对象数组的形式,因为对象数组可以向Object进行转型操作。
- 对象序列化过程:
- 把类名、属性的类型、属性的值以二进制方式写入文件保存,在需要的时候读取该文件,再根据保存的信息重新创建一个对象到内存中,称为还原。序列化不仅仅是把有用的属性值保存下来,还要保存类型和类信息。
- 在实现对象传输操作时,如果使用Serializable方式的序列化,不是最优的方式,因为这种方式会传输除了必须要的数据,还额外传输了类信息和属性信息,从这个点考虑就是浪费。牺牲性能,降低传输效率。
- 字节数组流
- 动态数组
- ByteArrayInputStream
- 内部维护有缓存数组.不关联文件,无需关闭,
- 所有的操作都基于内存。内部的缓冲区是一个动态数组(算法是原来长度*2)
- 该缓冲区包含从流中读取的字节。内部计数器跟踪 read 方法要提供的下一个字节
- 关闭 ByteArrayInputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException
- 字节数组流的本质就是使用 IO 流的操作方式来管理动态数组。
- ByteArrayOutputStream
- 此类实现了一个输出流,其中的数据被写入一个 byte 数组。
- 缓冲区会随着数据的不断写入而自动增长。
- 可使用 toByteArray() 和 toString() 获取数据。
- 关闭 ByteArrayOutputStream 无效。此类中的方法在关闭此流后仍可被调 用,而不会产生任何 IOException
- 数据流
- DataInputStream
- 数据流输入允许程序以与机器无关的方式从文件读取基本的数据类型
- DataInputStream 对于多线程访问不一定是安全的
- 线程安全是可选的, 它由此类方法的使用者负责。
- DataOutputStream
- 数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。
- 读取时的顺序要和写入的顺序一致。
- UTF
- DataInputStream
- 字符串流
- StringReader
- 源数据为String
- StringWriter
- 一个字符流,可以用其回收在字符串缓冲区中的输出来构造字符串。 关闭 StringWriter 无效。此类中的方法在关闭 该流后仍可被调用,而不会产生任何 IOException。
- 用流的形式来处理字符, 内部操作都在内存中,无需关闭,不会有 IOException
- 字符串流与字节数组流类似,都是内存操作流。
- StringReader
- RAF
- 特点:
- RandomAccessFile是java.io包的类,从Object直接继承而来
- 只可以对文件进行操作(读取/写入)
- r 当文件不存在时会报异常
- rw 当文件不存在时,会自己动创建文件,当文件已经存在时, 不会对原有文件进行覆盖
- rws
- rwd
- RandomAccessFile有强大的文件读写功能,其内部是大型 byte[],可以通过seek(),getFilePointer()等方法操作的 指针,方便对数据进行写入与读取。还可以对基本数据类型进行直接的读和写操作
- RandomAccessFile的绝大多数功能,已经被JDK 1.4的nio的“内存映射文件(memory-mapped files)”给取代了,你该考 虑一下是不是用“内存映射文件”来代替RandomAccessFile了。
- 默认seek()多少?
- 可以通过getFilePointer() 返回此文件中的当前偏移量。
- seek(long pos)设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。
- skipBytes(int n) 尝试跳过输入的 n 个字节以丢弃跳过的字节。
- 特点: