java序列化和反序列化工具_Java 序列化和反序列化工具类并解决StreamCorruptedException问题 | 学步园...
问题:
若通过ObjectOutputStream向一个文件中多次以追加的方式写入Object,为什么用ObjectInputStream读取这些Object时,会产生StreamCorruptedException
原因:
使用缺省的serializetion的实现时,一个ObjectOutputStream的构造和一个ObjectInputStream的构造必须一一对应,ObjectOutputStream的构造函数会向输出流中写入一个标识头,而ObjectInputStream会首先读入这个标志头,因此,多次以追加方式向一个文件写入Object时,该文件将会包含多个标志头,所以用ObjectInputStream来deserialize这个ObjectOutputStream时,将产生StreamCorruptedException。
解决方案:
构造一个ObjectOutputStream的子类,并覆盖writeStreamHeader()方法,被覆盖后的writeStreamHeader()方法应判断是否为首次向文件中写入Object,是则调用super.writeStreamHeader();若否,即以追加方式写入Object时,则应调用ObjectOutputStream.reset()方法。
案例:
创建测试类,在控制台上显示添加学生信息,要求程序循环运行,并依次提示接收学生类的所有属性值,保存到学生对象中,再将学生对象保存到集合对象中,并提示“是否继续添加(y/n):”,如果选择“y”则继续添加,否则退出循环,并将保存学生数据的集合对象通过序列化保存到“student.dat”文件中。然后实现从“student.dat”文件中反序列化保存学生数据的集合对象,并遍历打印输出学生信息。
解决StreamCorruptedException的错误:
/**
* 这个类可以避免StreamCorruptedException
* @author Liao
*
*/
public class MyObjectOutputStream extends ObjectOutputStream {
//无参构造函数
public MyObjectOutputStream() throws IOException, SecurityException {
super();
}
//有参构造函数
public MyObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
/**
* 重写writeStreamHeader()方法
*/
@Override
protected void writeStreamHeader() throws IOException {
// TODO Auto-generated method stub
return ;
}
}
工具类:
public class SerializableUtil implements Serializable{
private static final long serialVersionUID = 1L;
/**
* 序列化对象
* 用户传一个Object类型对象,和要序列化到的文件路径即可进行序列化
* @param obj对象
* @param path 对象要被序列化到的文件路径
*/
public static void serializObject(Object obj,String path){
//创建文件
File file = new File(path);
//判断文件是否存在
if (!file.exists()){
//如果文件不存在,就创建文件
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
//创建ObjectOutputStream
ObjectOutputStream objectOutputStream = null;
try {
//定义FileOutputStream,用于创建ObjectOutputStream
OutputStream outputStream = new FileOutputStream(file, true);
if (file.length() < 1){
objectOutputStream = new ObjectOutputStream(outputStream);
} else {
objectOutputStream = new MyObjectOutputStream(outputStream);
}
//把对象序列化到文件中
objectOutputStream.writeObject(obj);
} catch (Exception e) {
e.printStackTrace();
} finally {//强制关闭ObjectOutputStream
try {
objectOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 反序列化一个对象
*
* @param path 要反序列的文件的路径
* @return 返回一个被反序列化的对象
*/
@SuppressWarnings("resource")
public static Object unserializObject(String path){
//定义一个对象
Object obj = null;
//创建一个文件
File file = new File(path);
try {
//创建文件输入流
InputStream inputStream = new FileInputStream(file);
//通过文件输入流创建ObjectInputStream
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
//获取一个对象
obj = objectInputStream.readObject();
} catch (Exception e) {
e.printStackTrace();
}
//返回一个对象
return obj;
}
/**
* 序列化一个集合
* 用户传一个集合和要序列化到的路径即可进行序列化
* @param collections 集合
* @param path 要序列化的路径
*/
public static void serializList(List collections,String path){
//创建文件
File file = new File(path);
//判断文件是否存在
if (!file.exists()){
//如果文件不存在,就创建文件
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
//创建ObjectOutputStream
ObjectOutputStream objectOutputStream = null;
try {
//定义FileOutputStream,用于创建ObjectOutputStream
OutputStream outputStream = new FileOutputStream(file, true);
if (file.length() < 1){
objectOutputStream = new ObjectOutputStream(outputStream);
} else {
objectOutputStream = new MyObjectOutputStream(outputStream);
}
//遍历集合,然后把对象序列化到文件中
for (T collection : collections){
objectOutputStream.writeObject(collection);
}
} catch (Exception e) {
e.printStackTrace();
} finally {//强制关闭ObjectOutputStream
try {
objectOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 反序列化一个List集合
* 因为文件中有多个对象,如何在反序列化到末尾时,终止反序列化呢?
* 这里有一个技巧,我们可以通过一个死循环,一直读知道抛出EOFException时就break退出循环
* @param path路径
* @return 返回一个集合
*/
@SuppressWarnings("unchecked")
public static List unserializList(String path){
//创建一个文件
File file = new File(path);
//创建一个List集合用于存储反序列化后的对象
List collections = new ArrayList();
//定义ObjectInputStream
ObjectInputStream objectInputStream = null;
try {
//创建文件输入流
InputStream inputStream = new FileInputStream(file);
objectInputStream = new ObjectInputStream(inputStream);
//获取一个对象
while (true){
try {
//反序列化一个对象
T t = (T) objectInputStream.readObject();
//把该对象添加到集合中
collections.add(t);
} catch (EOFException e) {
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
objectInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//返回一个对象
return collections;
}
}
测试类:
/**
* 测试类
* @author Liao
*
*/
public class SerializationTest {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
boolean flag = true;
//创建集合用于存放实体对象
List persons = new ArrayList();
while (flag) {
// 输入用户ID
System.out.print("请输入UID:");
Integer uid = in.nextInt();
// 输入用户名
System.out.print("请输入用户名:");
String uname = in.next();
// 输入性别
System.out.print("请输入性别:");
String gender = in.next();
//把Person对象存到集合中
persons.add(new Person(uid, uname, gender.equals("男")? Gender.MAN : Gender.WOMEN));
// 是否继续
System.out.print("是否继续? y/n:");
String ifContinue = in.next();
if (ifContinue.equals("n")) {
flag = false;
}
}
//序列化
SerializableUtil.serializList(persons, "D:\\liaozhongmin.txt");
//反序列化
List collections = SerializableUtil.unserializList("D:\\liaozhongmin.txt");
System.out.println(collections);
}
}
java序列化和反序列化工具_Java 序列化和反序列化工具类并解决StreamCorruptedException问题 | 学步园...相关推荐
- java中bean是什么_java中bean是什么意思?有什么作用 | 学步园
Bean的中文含义是"豆子",顾名思义JavaBean是一段Java小程序.JavaBean实际上是指一种特殊的Java类,它通常用来实现一些比较常用的简单功能,并可以很容易的被重 ...
- java判断简体和繁体字_java获取系统语言(区分简体中文和繁体中文) | 学步园...
之前做android应用时遇到过一个问题,就是根据语言的不同而显示不同的内容 网上很多代码都是错误的,起码无法区分简体和繁体,这里给出一种方法 不涉及android任何知识,所以就归类到java这边了 ...
- java 显示多行歌词_Java Swing制作多行滚动歌词显示控件 | 学步园
首先上图一张,为最终制作的效果图,不喜欢或感到失望的朋友可以先行离开 大家已经看到效果图了.那么下面就介绍设计思路和源代码 首先要想显示歌词,就要对歌词文件进行抽象.下面这个类是对某一行歌词文件进行了 ...
- java序列化算法透析_Java序列化机制与原理的深入分析
Java序列化算法透析 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.Java序列化API提供一 ...
- java序列化算法透析_Java序列化算法透析
/** * 轉載請注明作者longdick http://longdick.iteye.com * */ Java 序列化算法透析 Serialization (序列化)是一種將對象以一連串的 ...
- java输出set集合元素_java Set集合,HashSet类详细介绍
下面要给大家介绍的就是java Set集合方面的内容,本文主要讲到了HashSet类的一些知识,主要包括了HashSet类的特点,HashSet 类的常用构造方法重载形式以及代码演示了创建两种不同形式 ...
- java jstack 工具_java命令之jstack工具
1.总述 jstack是jvm虚拟机自带的一种堆栈分析工具,用于打印出给定的java进程或者core file或者远程调试服务的堆栈信息等.主要分为两个功能如下: a.针对活着的进程做本地的或者远程的 ...
- java socket 工具_java Socket简易聊天工具
本文实例为大家分享了一款Socket简易聊天工具,希望大家喜欢. 代码运行如图,看起来还不错 服务端 package qiu; import java.awt.BorderLayout; import ...
- java 日历工具_java之日历处理工具类Calendar类
编程语言 java之日历处理工具类Calendar类 字号+ 作者:小虾米 2016-11-08 12:43 Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR.MONTH.DAY_O ...
最新文章
- Ubuntu 12.10 拨号上网及停用方法
- vba去oracle数据后乱码,vba中读取utf-8文件乱码问题
- Netbeans配置Java SE嵌入式平台(树莓派)
- 为啥led灯用一年后暗了很多_嫌原车的卤素“蜡烛灯”太暗,想换掉,该选氙气灯还是LED灯?...
- Lightoj1014【基础题】
- 斐波那契数列的实现(简单递归和动态规划)
- [OS复习]设备管理2
- 【Python 必会技巧】对字典按照键(key)或者值(value)排序
- matplotlib绘图_使用matplotlib库绘图
- Codeforces Round #500 (Div. 2) C.Photo of The Sky
- 通过jQuery获取窗口的高度
- 橱柜高度与身高对照表_170身高和橱柜高度对照表 详细解析
- linux下mongodb的安装及启动
- Bootstrap-按钮
- javascript模板插件amaze.js
- ST、SC、FC、LC光纤接头区别
- 怎么才能够坚持做一件事并且把它做好?
- extern 关键字详解
- UVA 1600 Patrol Robert 巡逻机器人 (启发搜索BFS)
- squid笔记下载_Squid笔记
热门文章
- CPQuery, 解决拼接SQL的新方法
- idea配置 Tomcat Deployment添加时没有Artifact...选择的解决方案
- JsonMappingException:找不到类型[simple type,class]的合适构造函数:无法从JSON对象实例化
- File.separator或File.pathSeparator
- 尝试远程添加Git存储库时收到“致命错误:不是git存储库”
- 对volatile的理解
- 阿里云云盾-智能风控(公测)发布
- PhpStorm+Homestead+Xdebug调试Laravel
- 贵州省新农合业务系统容灾技术支撑服务项目
- zabbix_agentd.conf配置文件详解