Java ObjectInputStream和ObjectOutputStream类的用法(附带实例)
Java 中的 ObjectInputStream 类和 ObjectOutputStream 类分别是 InputStream 类和 OutputStream 类的子类,以“对象”为数据源,但是必须将传输的对象进行序列化与反序列化操作。
ObjectInputStream 类和 ObjectOutputStream 类的构造方法如下:
当使用对象流写入或读取对象时,需要保证对象是可序列化的。这是为了保证能把对象写入文件中,并且能再把对象正确地读回到程序中。
序列化是指先将内存中对象的相关信息(包括类、数字签名、对象除 transient 和 static 之外的全部属性值,以及对象的父类信息等)进行编码,再写到外存中。如果与序列化的顺序相反,就叫反序列化,即从外存中读取序列化的对象信息,并重新解码组装为内存中一个完整的对象。
一个类如果实现了 Serializable 接口,那么这个类创建的就是可序列化的对象。Serializable 接口中的方法对程序是不可见的,因此实现该接口的类不需要实现额外的方法。
如果把一个序列化的对象写入对象输出流中,Java 虚拟机就会实现 Serializable 接口中的方法,将一定格式的文本(对象的序列化信息)写入目的地中。当 ObjectInputStream 对象流从文件中读取对象时,就会从文件中读回对象的序列化信息,并根据对象的序列化信息创建一个对象。
【实例】ObjectInputStream 类和 ObjectOutputStream 类的应用。
ObjectInputStream 类和 ObjectOutputStream 类的构造方法如下:
ObjectInputStream(InputStream in) ObjectOutputStream(OutputStream out)ObjectOutputStream 类的指向是一个输出对象流,当准备将一个对象写入文件中时,先用 OutputStream 类的子类创建一个输出流。同样,ObjectInputStream 类的指向是一个输入流对象,当准备从文件中读入一个对象到程序中时,先用 InputStream 类的子类创建一个输入流。
当使用对象流写入或读取对象时,需要保证对象是可序列化的。这是为了保证能把对象写入文件中,并且能再把对象正确地读回到程序中。
序列化是指先将内存中对象的相关信息(包括类、数字签名、对象除 transient 和 static 之外的全部属性值,以及对象的父类信息等)进行编码,再写到外存中。如果与序列化的顺序相反,就叫反序列化,即从外存中读取序列化的对象信息,并重新解码组装为内存中一个完整的对象。
一个类如果实现了 Serializable 接口,那么这个类创建的就是可序列化的对象。Serializable 接口中的方法对程序是不可见的,因此实现该接口的类不需要实现额外的方法。
如果把一个序列化的对象写入对象输出流中,Java 虚拟机就会实现 Serializable 接口中的方法,将一定格式的文本(对象的序列化信息)写入目的地中。当 ObjectInputStream 对象流从文件中读取对象时,就会从文件中读回对象的序列化信息,并根据对象的序列化信息创建一个对象。
【实例】ObjectInputStream 类和 ObjectOutputStream 类的应用。
import java.io.*; import java.util.Date; public class Example { public static void main(String[] args) throws IOException, ClassNotFoundException { // 写文件 write(); // 读文件 read(); } // 使用对象输出流将数据写入文件中 public static void write() { // 创建对象输出流,并包装缓存流,增加缓存功能 try ( OutputStream fileos = new FileOutputStream("D:\\chapter10\\2.txt"); BufferedOutputStream bufferos = new BufferedOutputStream(fileos); ObjectOutputStream objectos = new ObjectOutputStream(bufferos); ) { // 对象流也可以对基本数据类型执行读/写操作 objectos.writeInt(5); objectos.writeDouble(Math.random()); objectos.writeChar('A'); objectos.writeBoolean(true); objectos.writeUTF("你好,Java!"); // Date是系统提供的类,已经实现了序列化接口 // 如果是自定义类,那么需要自己实现序列化接口 objectos.writeObject(new Date()); } catch (Exception e) { e.printStackTrace(); } } // 使用对象输入流将数据读入程序中 public static void read() { try ( InputStream fileis = new FileInputStream("D:\\chapter10\\2.txt"); BufferedInputStream bufferis = new BufferedInputStream(fileis); ObjectInputStream objectis = new ObjectInputStream(bufferis); ) { // 使用对象输入流按照写入顺序读取 System.out.println("读取整型数: " + objectis.readInt()); System.out.println("读取浮点类型数: " + objectis.readDouble()); System.out.println("读取字符: " + objectis.readChar()); System.out.println("读取布尔类型数据: " + objectis.readBoolean()); System.out.println("读取字符串: " + objectis.readUTF()); System.out.println("读取一个对象: " + objectis.readObject().toString()); } catch (Exception e) { e.printStackTrace(); } } }运行结果为:
读取整型数:5
读取浮点类型数:0.8343602945381245
读取字符:A
读取布尔类型数据:true
读取字符串:你好,Java!
读取一个对象:Mon Aug 15 00:14:38 CST 2022