I/O流(对象流和序列化)
程序员文章站
2022-07-09 23:02:58
...
我们这里提到了对象流那么自然就要提到序列化
对象输入流就是ObjectInputStream
对象输出流就是ObjectOutPutStream
这里可能就要比较复杂些了既然涉及到了对象,那么我们就先来写一个类吧。
比方说我们写一个Car的类吧,我相信每个奋斗的男人都梦想有自己的一台车吧
好我们就把这个类写出来
我们简单的写一个汽车类
/**
* @author Hercules
* @version 创建时间:2020年2月13日 下午8:07:02
* 车类
*/
public class Car {
private String color; //汽车的颜色
private String brand; //汽车的品牌
private String num; //汽车的车牌号
public Car() {
super();
}
public Car(String color, String brand, String num) {
super();
this.color = color;
this.brand = brand;
this.num = num;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
@Override
public String toString() {
return "color=" + color + ",brand=" + brand + ",num=" + num + "&";
}
}
而后我们再书写操作代码
/**
* 对象输入输出流
*/
public static void objectRW() {
Car car = new Car("红色","法拉利","川L88888");
OutputStream os = null;
ObjectOutputStream oos = null;
try {
os = new FileOutputStream("d://car.txt");
oos = new ObjectOutputStream(os);
oos.writeObject(car);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
我们上面给了一台法拉利的对象,并赋予了一个流弊的车牌,让我们运行一下。
没错这里出问题了,那么是为什么呢,这里就涉及到了序列化的问题。
那么序列化是什么呢,其实我们这里可以把序列化理解为一种规则,底层是什么先不说了,这里我们先理解一下什么是序列化。
我们比较通俗的理解,比如我们现在要搬家,没错要搬家,但是现在的家具体积都比较庞大,而房子的门普遍都比较好,那么我们的家具就通过不了那个门。
那总得搬家呀,一般怎么办呢,一般都是先在旧房子里面把这些沙发,床呀这些东西啥的都拆了,而后搬到新家,然后再组装回去。
这个时候这个拆和组装就称为序列化和反序列化。
我们这里就是把对象拆成字节就是对象和字节之间的转换。
序列化应该就比较好理解吧,而且序列化在代码也是比较简单的。
我们只需要这么改:
/**
* @author Hercules
* @version 创建时间:2020年2月13日 下午8:07:02
* 车类
*/
public class Car implements Serializable{
private String color; //汽车的颜色
private String brand; //汽车的品牌
private String num; //汽车的车牌号
public Car() {
super();
}
public Car(String color, String brand, String num) {
super();
this.color = color;
this.brand = brand;
this.num = num;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
@Override
public String toString() {
return "color=" + color + ",brand=" + brand + ",num=" + num + "&";
}
}
没错这两个类的区别就是实现了这个接口,然而接口里面没有方法,我们只需要实现就好了。
然后我们car.txt里面的内容我们就看不懂了没错你肯定看不懂,它是长这个样子的:
这个时候就涉及到了反序列化的问题,我们需要把这个对象读取回来:
我们将objectRW这个方法修改如下
/**
* 对象输入输出流
*/
public static void objectRW() {
Car car = new Car("红色","法拉利","川L88888");
OutputStream os = null;
ObjectOutputStream oos = null;
try {
os = new FileOutputStream("d://car.txt");
oos = new ObjectOutputStream(os);
oos.writeObject(car);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//读取对象
InputStream is = null;
ObjectInputStream ois = null;
try {
is = new FileInputStream("d://car.txt");
ois = new ObjectInputStream(is);
Car o = (Car)ois.readObject();
System.out.println(o);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally {
if(ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
在控制台就可以得到如下结果