序列化和反序列化的过程中,我们会用到ObjectOutputStream和ObjectInputStream
ObjectOutputStream用于将对象系列化,它可以把一个对象用二进制的方式表示,可以把一个对象通过ObjectInputStream进行还原。这在网络环境下是非常有用的。可以把一个object通过二进制流在网络上进行传播。
通过代码说话吧:
ObjectOutputStream objput=null;
File outTo=new File("D:/students.dat");
FileOutputStream fileout=new FileOutputStream(outTo,true);
objput=new ObjectOutputStream(fileout);
Student ms=new Student(12345,'男',21,"明帅","软件工程");
objput.writeObject(ms);
objput.writeObject(ms);
objput.flush();
这段代码把对象序列化后存放在文件中,前面的一篇文章我详细讨论了系列化算法,系列化算法首先会在文件中写入一些头部信息,声明使用了序列化协议和使用系列化的版本,如下图所示,黄色部分代表写入的对象。
再进行反序列化时,这没有任何问题。
但注意上面的这段代码:FileOutputStream(outTo,true);
True表示可以在文件后面追加信息,当再次调用这段代码时,会打开一个新的流,在写入时头部信息重新会输入一遍。写入后如下所示:
这时再进行反序列化操作,后面的那个头就无法识别,会终止反序列化,并抛出java.io.StreamCorruptedException
异常。通常情况下不可能一次把所有的对象通过一个流一次性写入文件,不可避免的会出现上面的问题,所以解决这个问题就很有必要。
解决这个问题需要重写一个类,让它继承ObjectOutputStream类,并覆写其中的writeStreamHeader方法。这个方法定义如下:
writeStreamHeader
protected void writeStreamHeader()
throws IOException
提供 writeStreamHeader 方法,这样子类可以将其自身的头部添加或预加到流中。它可以将幻数 (magic number) 和版本写入流。
这个方法可以自定义流的头部,也就上面图中的黄色部分。
还要用到另外的一个函数reset(),其定义如下:
reset
public void reset()
throws IOException
重置将丢弃已写入流中的所有对象的状态。重新设置状态,使其与新的 ObjectOutputStream 相同。将流中的当前点标记为 reset,相应的 ObjectInputStream 也将在这一点重置。以前写入流中的对象不再被视为正位于流中。它们会再次被写入流。
用上面的那两个方法,我们可以对ObjectOutputStream 进行一下改造:
public class ReuseObjectOutputStream extends ObjectOutputStream{
public ReuseObjectOutputStream(OutputStream arg0) throws IOException {
super(arg0);
// TODO Auto-generated constructor stub
}
public void writeStreamHeader(){
try {
this.reset();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("流重置出现问题....");
}
}
}
writeStreamHeader方法被ObjectOutputStream对象在写入具体的数据时自动调用。Reset()方法把流之前写入的所有信息都抹掉,相当于进行如下图A到图B的转换,这样序列化后就没有任何问题。
具体使用的时候要注意一点,因为头部信息是必不可少的,否则无法被反系列化,当上述逻辑中,当文件中没有任何信息的时候,必须用到一个普通的ObjectOutputStream进行数据的写入。以后的再次写入时用ReuseObjectOutputStream对象进入系列化。
转自:http://hi.baidu.com/xiyandada/item/dee3a4e79c0fb91a585dd8ee
相关推荐
【Android多点触控技术实战】在Android应用开发中,多点触控技术是一项重要的交互设计,它使得用户可以通过两个或更多的手指同时操作屏幕,从而实现更丰富的交互体验。在这个场景下,我们专注于如何实现图片的自由...
3. 异常处理:文件中提及了“Exception”、“InterruptedException”、“StreamCorruptedException”,这些都是Java异常处理的一部分。在Java中,异常处理通过“try”、“catch”、“finally”和“throw”、“throws...
在编程领域,串行化(Serialization)是一种将对象的状态转换为可以存储或传输的数据格式的过程。这个过程使得数据能够在不同的...通过上述知识点的学习和实践,你将能够更好地利用Java的串行化特性来解决实际问题。
它们提供了一种标准的解决方案,有助于提高代码的可读性和可维护性。 **工厂模式**:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 **实现方式**: 1. **简单工厂**:由一个工厂对象决定...
WxParse-微信小程序富文本解析自定义组件,支持HTML和markdown解析
那些年,与你同分同位次的同学都去了哪里?全国各大学在辽宁2020-2024年各专业最低录取分数及录取位次数据,高考志愿必备参考数据
Chartjs微信小程序改编_Chartjs-wecat-mini-app
网上好不容易找到的,特此分享。
该项目汇集了55个文件,涵盖Java编程语言的源码和小型作品,具体包括15个XML配置文件、13个Java源文件、12个Git忽略文件、6个IML项目文件、5个文档文件、2个Markdown文件、1个文档和1个PNG图像文件。这些文件构成了一个完整的Java开发资源包。
那些年,与你同分同位次的同学都去了哪里?全国各大学在辽宁2020-2024年各专业最低录取分数及录取位次数据,高考志愿必备参考数据
该项目为2022年暑期实习期间由190822班贺忍小组开发的应急互助信息管理系统源码,采用Java作为后端开发语言,并结合Vue、JavaScript、HTML、SVG等前端技术实现。该系统源码包含684个文件,其中Java文件282个,Vue文件101个,SVG文件87个,JavaScript文件84个,XML文件34个,PNG文件26个,JPG文件13个,VM文件13个,SCSS文件9个,BAT文件7个。该系统旨在提供高效、便捷的应急互助信息管理服务。
全国大学生电子设计大赛项目合集全国电赛优秀作品电赛B题风力摆控制系统设计(原理图+源代码+设计报告等)
该项目为基于SpringBoot框架的Java课程资料,包含35个文件,其中26个为Java源文件,3个为SQL脚本,1个为Git忽略文件,1个为Maven构建配置文件,1个为XML配置文件,1个为Markdown文档,以及1个属性文件。这些资料旨在辅助教学活动,适用于相关Java课程的教学和实践。
那些年,与你同分同位次的同学都去了哪里?全国各大学在辽宁2020-2024年各专业最低录取分数及录取位次数据,高考志愿必备参考数据
职业心理测试综合素养测试32个文件职业心理测试综合素养测试32个文件
STM32硬件资料硬件工程师手册全STM32硬件资料硬件工程师手册全
微信小程序关注WXReading阅读
那些年,与你同分同位次的同学都去了哪里?全国各大学在辽宁2020-2024年各专业最低录取分数及录取位次数据,高考志愿必备参考数据
数据集格式:Pascal VOC格式+YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):2694 标注数量(xml文件个数):2694 标注数量(txt文件个数):2694 标注类别数:4 标注类别名称:["concrete_mixer_truck","dump","dump_truck","excavator"] 标注类别中文名称:混凝土搅拌车、自卸汽车、自卸卡车、挖掘机 每个类别标注的框数: concrete_mixer_truck 框数 = 744 dump 框数 = 17 dump_truck 框数 = 2605 excavator 框数 = 1901 总框数:5267 使用标注工具:labelImg 标注规则:对类别进行画矩形框
微信小程序图表库,微信小程式图表_wx-Charts