对象流—ObjectInputStream 和 ObjectOutputStream
对象流(ObjectInputStream和ObjectOutputStream)是Java中用于读写对象的流,可以将对象直接写入到流中,或者从流中读取对象。
ObjectOutputStream将对象序列化为字节流,可以将对象写入文件或网络流中。ObjectInputStream则将字节流反序列化为对象,可以从文件或网络流中读取对象。
使用对象流的步骤如下:
-
创建ObjectOutputStream时,将要写入的流作为参数传入构造函数。例如,可以使用FileOutputStream创建一个ObjectOutputStream对象并指定要写入的文件。
-
使用ObjectOutputStream的writeObject方法将对象写入流中。该方法将对象序列化为字节流并写入到流中。
-
创建ObjectInputStream时,将要读取的流作为参数传入构造函数。例如,可以使用FileInputStream创建一个ObjectInputStream对象并指定要读取的文件。
-
使用ObjectInputStream的readObject方法从流中读取对象。该方法将字节流反序列化为对象并返回。
注意事项:
-
要将对象写入流中,对象的类必须实现Serializable接口。Serializable是一个标记接口,表示该类可以被序列化。
-
被序列化的对象必须是可传递的,即它的成员变量的类型也必须实现Serializable接口。
-
在反序列化时,如果对象的类发生了变化(例如添加或删除了字段),反序列化可能会失败。
-
对象流的读写操作是阻塞的,即在读或写操作完成之前,程序会一直等待。因此,在使用对象流时要注意流的关闭操作,以防止资源泄漏。
-
对象流也可以用于在进程间传递对象。可以通过网络流将对象从一个进程发送到另一个进程。
除了对象流,还有其他类型的流,如字节流和字符流,可以用于读写不同类型的数据。对象流在处理对象时非常方便,因为它们可以直接读写对象,而无需将对象转换为字节或字符。
使用ObjectOutputStream序列化基本数据类型和一个Dog对象(name,age),并保存到data.dat文件中;使用ObjectInputStream读取data.dat并反序列化
public class ObjectOutputStream01 {
public static void main(String[] args) throws IOException {
String filePath="D:/javaTest/data.dat";//序列化后保存的文件路径
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(filePath));
//序列化数据
os.writeInt(100);
os.writeBoolean(true);
os.writeChar('A');
//保存dog对象
os.writeObject(new Dog("小狗", 3));
System.out.println("数据序列化完成!");
os.close();
}
}
反序列化
public class ObjectInputStream01 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
String filePath="D:/javaTest/data.dat";//存放序列化后的对象文件
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
Object o = ois.readObject();
System.out.println(o.getClass());
System.out.println(o);
Dog dog = (Dog) o;
System.out.println(dog.getName());
ois.close();
}
}
注意:序列化后,保存的文件格式,不是纯文本,而是按照他的格式来保存;反序列化的顺序需要和保存的顺序一致,在进行反序列化时,在反序列化的类的包下必须要有与序列化类中的相同类的定义,否则会出现类型转换异常;每次修改代码都需要全部重新执行一遍,否则编译器会认为版本不一致从而导致运行异常