1.由一个需求引入对象流
1.1 需求描述
1.将【基本数据类型 int a = 10】, 保存到文件中,并能够从文件中恢复;
2.将 【对象类型 new Dog("旺财",3)】,保存到文件中,并能够从文件中恢复。
1.2 需求分析
上面的两个需求可做如下分析:
1.需要将数据保存到文件中,(这个可以通过文件的写操作实现)
2.保存数据的同时,需要将 数据的类型也一起保存起来?(这个使用普通的流无法实现)
3.读取文件的时候,也要把 数据的类型读取出来?(这个使用普通的流无法实现)
1.3 需求解决
上述的需求,就是需要把 【基本数据类型】和【对象类型】进行【序列化】和【反序列化】。
2.补充-序列化的概念
【序列化】:就是 保存数据时,同时保存 数据的类型+数据值
【反序列化】:就是 读取数据时,同时读取 数据的类型+数据值
[注意]:
在将对象进行序列化的时候,该对象的类必须是可序列化的。
实现方式推荐 通过实现 Serializable 接口。
3.初识对象流
3.1 ObjectOutputStream
ObjectOutputStream : 提供
序列化
功能,可以实现保存 数据类型+数据值 到文件中去。
类的继承关系图如下:
3.2 ObjectInputStream
ObjectInputStream : 提供
反序列化
功能,可以实现 从文件中 读取 数据类型+数据值。
类的继承关系图:
4.对象流的使用规则
在使用 对象流的时候,需要注意以下几个方面:
1.自定义的类需要 实现 Serializable 接口来确保可以进行序列化;
2.序列化的类中,建议添加 SerialVersionUID来提高版本的兼容性;
3.序列化对象时,默认将对象中的所有属性都进行序列化,但static 和 transient 修饰的成员除外;
4.序列化对象时,要求对象的属性的类型,也需要实现序列化接口;
5.序列化具有继承性,即一个类实现了序列化接口,则其子类也默认实现了序列化接口。
6.使用对象流在进行 序列化 和 反序列化 的时候,顺序要一致,即先写出去的,就要先读进来。
5.ObjectOutputStream使用案例
将 对象 序列化 保存
5.1 一个自定义类,实现了Serializable接口
package com.northcastle.domain;
import java.io.Serializable;
/**
* author : northcastle
* createTime:2022/1/8
* 一个实现了序列化接口的类
*/
public class Dog implements Serializable {
private String name;
private Integer age;
private Integer color;
public Dog() {
}
public Dog(String name, Integer age, Integer color) {
this.name = name;
this.age = age;
this.color = color;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getColor() {
return color;
}
public void setColor(Integer color) {
this.color = color;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
", color=" + color +
'}';
}
}
5.2 对象流的使用
package com.northcastle.outputStream_;
// 注意 : 引入自定义的类,各位看官在实际写的时候注意自己的包路径即可
import com.northcastle.domain.Dog;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
/**
* author : northcastle
* createTime:2022/1/8
* 对象输出流 : 保存类型+数据
* 要保存的对象必须序列化
*/
public class ApplicationObjectOutputStream {
public static void main(String[] args) {
//1.声明一个输出的文件位置
String filePath = "D:\\EDailyRoutine\\java-io-test\\ObjectOutputStream.data";
//2.声明一个文件输出流
FileOutputStream fos = null;
//3.声明一个对象输出流
ObjectOutputStream oos = null;
try {
//4.实例化 文件输出流
fos = new FileOutputStream(filePath);
//5.实例化 对象输出流
oos = new ObjectOutputStream(fos);
//6.执行写操作 : 进行序列化保存
oos.writeInt(100); // 写 Integer
oos.writeFloat(200.123f); // 写 Float
oos.writeDouble(300.2d); // 写 Double
oos.writeBoolean(false); // 写 Boolean
oos.writeChar(95); // 写 Char
oos.writeUTF("你好,我是对象输出流!"); // 写字符串 String
oos.writeObject(new Dog("旺财",3,123)); // 写自定义的对象
oos.writeUTF("============================"); // 写字符串
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
// 7.关闭最外层的 处理流 ObjectOutputStream
if (oos != null){
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
5.3 执行结果
找到输出的文件,打开后可以看到被序列化的内容:
6.ObjectInputStream使用案例
将数据 反序列化 读入到内存中.
此案例结合 上面的第5小结中序列化的数据。
【注】:反序列化的顺序,必须和 序列化的顺序相同!
6.1 读取代码
package com.northcastle.inputStream_;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
/**
* author : northcastle
* createTime:2022/1/8
* 对象输入流 : 反序列化读取文件内容
*/
public class ApplicationObjectInputStream {
public static void main(String[] args) {
//1.指定文件路径
String filePath = "D:\\EDailyRoutine\\java-io-test\\ObjectOutputStream.data";
//2.声明 文件输入流
FileInputStream fis = null;
//3.声明 对象输入流
ObjectInputStream ois = null;
try {
//4.实例化 文件输入流
fis = new FileInputStream(filePath);
//5.实例化 对象输入流
ois = new ObjectInputStream(fis);
//6.执行反序列化操作:读取内容到程序中
System.out.println(ois.readInt()); // 读 Integer
System.out.println(ois.readFloat()); // 读 Float
System.out.println(ois.readDouble()); // 读 Double
System.out.println(ois.readBoolean()); // 读 Boolean
System.out.println(ois.readChar()); // 读 Char
System.out.println(ois.readUTF()); // 读 字符串 String
System.out.println(ois.readObject()); // 读 对象
System.out.println(ois.readUTF()); // 对 字符串 String
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally {
//7.关闭对象输入流
if (ois != null){
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
6.2 运行结果
能够正确的读取到 文件中的内容
7.完成
Congratulations!
You are one step closer to success!