这几天上班看了点java的基础知识点,看到介绍序列化的基本问题是都是以介绍序列化一个和反序列化一个对象为例的,依此就想到了要是序列化一次多个序列化对象,再或者不同时间多次序列化对象怎么做,于是动手试了下,发现了不少问题,由于是小菜搞了好久上网找,才得以解决问题,废话不多说了,下面直接进入正题。
(一).java序列化的基本原理知识
参考转自:http://yuyiming.iteye.com/blog/1277089
该博客里面基本的介绍,这里不过多废话了。
(二).一次序列化多个对象及多次序列化产生的问题
对于一次序列化多个对象的话,就是多次调用writeObject()方法就可以了。然而要注意的一点就是在一次的序列化的过程中(写入文件到关闭文件的过程为一次序列化过程),ObjectOutputStream对象写对象的话,会写入一个header,也就是一次序列化的过程中会在文件开始的地方写入一个Header的信息到文件中,于此在多次序列化的过程中(如序列化一次关闭文件后,可能又需要往文件中序列化其他对象),此时就会继续在文件末尾(本次序列化的开头)写入Header的信息,如此如果进行反序列化的对象的时候会报如下错误java.io.StreamCorruptedException: invalid type code: AC,因为这是头的信息而不是对象的信息,为了解决这个办法,就必须在以后序列化的过程中不写入头文件即可:
解决方法:(详细见博客转自http://blog.sina.com.cn/s/blog_6145ed810100z143.html)
1.用同一个ObjectOutputStream写对象
2.但是大部分时候,要不断往某个文件记录对象,这样按照1的说法就要维护一个ObjectOutputStream,但是重启应用时候就会重新创建一个ObjectOutputStream对象,此时如果还是想往刚才那个文件里写对象的话,就会追加一个header。这样在读对象时读到这个位置就会报错。
解决方法是重写ObjectOutputStream的writeStreamHeader()方法
(三).多次序列化多个对象时的解决方法
上面解决了多次序列化的问题,为此我们发现他们在发序列化对象的时候,必须要知道序列化了多少 个对象,然后才能循环多少次把对象取出来,这样显然不是很方便,如果我文件和程序关闭了,我下次要是又想反的时候,怎么才知道以前序列化了多少个对象呢?为此我们通过如下的方法来解决,因为在readObject()的时候,每次都是反序列化一个对象,所以我们可以通过一个while(true)的循环来读取,当到文件最后的时候,会抛出EOFFileEnd的一个异常来解决。代码见下
public class SerializableTestListError {
private static List<Student> listStudentObject = new ArrayList<Student>();
private static List<Car> listCarObject = new ArrayList<Car>();
private static List<Object> listObject = new ArrayList<Object>();
public static void main(String[] args) throws IOException {
Student stu1 = new Student(01044444441, "yteng1", 204);
Student stu2 = new Student(00444344441, "yteng2", 421);
Car car1 = new Car("DazsAut00144444444444400o", "ShangHai", 2000400.0);
Car car3 = new Car("DazsAuto114444444441", "ShangHai", 2000400.0);
Car car2 = new Car("For14444444d", "JiangSu", 300040.00);
listObject.add(car2);
listObject.add(car1);
listObject.add(car3);
listObject.add(stu1);
listObject.add(stu2);
writeObject2File(listObject, "D:\\new.txt");
try {
readObjectFromFile("D:\\new.txt");
} catch (SerilizableException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void writeObject2File(List<Object> o, String fileName)
throws IOException {
File file = null;
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try {
file = new File(fileName);
fos = new FileOutputStream(file, true);
if (file.length() < 1) {
oos = new ObjectOutputStream(fos);
} else {
oos = new MyObjectOutputStream(fos);
}
for (int i = 0; i < o.size(); i++)
oos.writeObject(o.get(i));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fos != null)
fos.close();
if (oos != null)
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void readObjectFromFile(String fileName) throws Exception {
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fis = new FileInputStream(fileName);
ois = new ObjectInputStream(fis);
while (true)
System.out.println(ois.readObject());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
System.out.println("文件终止!~");
e.printStackTrace(); //此处解决序列化完成后的异常
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
System.out.println("输出结束~");
} finally {
try {
if (fis != null)
fis.close();
if (ois != null)
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
这里我一次序列化了多个对象。另外我们还可以用流机制来反序列化多个对象,代码如下:
public class SerializableTest {
private static List<Student> listStudentObject=new ArrayList<Student>();
private static List<Car> listCarObject=new ArrayList<Car>();
private static List<Object> listObject=new ArrayList<Object>();
public static void main(String[] args) throws IOException {
Student stu1=new Student(001, "yteng11", 20);
Student stu2=new Student(002,"yteng22",21);
Car car1=new Car("DazsAuto", "ShangHai", 200000.0);
Car car2=new Car("Ford","JiangSu",30000.00);
writeObject2File(stu1,"D:\\date.txt");
writeObject2File(stu2,"D:\\date.txt");
writeObject2File(car1,"D:\\date.txt");
writeObject2File(car2,"D:\\date.txt");
try {
readObjectFromFile("D:\\date.txt");
} catch (SerilizableException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
for(Iterator<Car> iterCar=listCarObject.iterator();iterCar.hasNext();){
System.out.println(iterCar.next());
}
for(Iterator<Student> iterStudent=listStudentObject.iterator();iterStudent.hasNext();){
System.out.println(iterStudent.next());
}
}
public static void writeObject2File(Object o,String fileName) throws IOException{
FileOutputStream fout=new FileOutputStream(fileName,true);
ObjectOutputStream sout=new ObjectOutputStream(fout);
sout.writeObject(o);
sout.close();
System.out.println("写入对象成功!");
}
public static void readObjectFromFile(String fileName) throws Exception{
FileInputStream fin=new FileInputStream(fileName);
BufferedInputStream bis=new BufferedInputStream(fin);
ObjectInputStream oip=null;
while(true){
try{
oip=new ObjectInputStream(bis); //每次重新构造对象输入流
}
catch(EOFException e)
{
e.printStackTrace();
System.out.println("已达文件末尾");//如果到达文件末尾,则退出循环
break;
}
Object object=new Object();
object=oip.readObject();
if(object instanceof Student) { //判断对象类型
listStudentObject.add((Student)object);
}
else if(object instanceof Car){
listCarObject.add((Car)object);
}
}
oip.close();
bis.close();
fin.close();
}
}
好了,第一次发帖也不知道怎么编辑,比较乱,有错误的话希望大侠指出。
分享到:
相关推荐
2. **使用`ObjectOutputStream.writeUnshared()`**:此方法序列化一个对象,但不会写入其类描述信息,适合序列化多个对象到同一文件,避免覆盖前面的类描述信息。不过,这种方法需要配合`ObjectInputStream....
Java反序列化是一种将已序列化的对象状态转换回对象的过程,它是Java平台中持久化数据的一种常见方式。在Java应用程序中,序列化用于保存对象的状态以便稍后恢复,或者在网络间传输对象。然而,这个过程也可能引入...
Java 序列化和反序列化是 Java 语言中的一种机制,用于将对象转换为字节流,以便在网络上传输或存储。序列化是将对象转换为字节流的过程,而反序列化是将字节流转换回对象的过程。 在 Java 中,序列化和反序列化是...
Java对象的序列化和反序列化是Java编程中一项...总结,Java对象的序列化和反序列化是Java编程中的基础概念,它涉及到数据持久化、网络通信等多个方面。理解并熟练运用这一技术,能够帮助开发者更有效地管理和传递数据。
下面是一个简单的序列化示例代码,展示了如何将一个`Box`对象序列化并存储到文件中,然后再从文件中读取出来: ```java package com.hotye.dchaoxiong.serializabletest; import java.io.FileInputStream; import ...
总结来说,C#和Java的序列化和反序列化机制都是各自语言中不可或缺的一部分,它们使得数据能够在不同环境之间自由流动。理解和掌握这些技术对于任何软件开发者来说都是非常重要的,特别是涉及到数据持久化、网络通信...
在这个特定的场景中,我们关注的是如何使用Java序列化来多次追加对象到一个TXT文件,而不是覆盖原有的内容,以及如何从TXT文件中反序列化这些对象并显示在控制台上。 首先,要实现序列化,我们的类必须实现`...
1. **创建文件输出流(FileOutputStream)**:首先需要创建一个指向序列化文件的输出流。 ```java FileOutputStream fs = new FileOutputStream("foo.ser"); ``` 2. **创建对象输出流(ObjectOutputStream)**:接着...
### Java序列化与反序列化详解 #### 一、Java序列化概述 Java序列化(Serialization)是一项重要的功能,它可以将对象的状态转化为一系列字节,从而实现对象的持久化存储或在网络上传输。序列化机制使得Java对象...
Xson是一个Java对象序列化和反序列化程序。支持Java对象到字节数组的序列化,和从字节数组到Java对象的反序列化。 Maven: <groupId>com.github.xsonorg</groupId> <artifactId>xson-core <version>1.0.1 ...
Java文件序列化是Java平台中一种重要的数据存储和交换机制,它允许我们将对象的状态转换为字节流,以便可以保存到磁盘、网络传输或在内存中存储,然后在需要时将这些字节流恢复为原来的对象。这个过程称为序列化...
Java的序列化与反序列化是Java开发中的一项重要技术,它允许我们将对象的状态转换为字节流,以便存储或在网络上传输。`Serializable`接口是Java提供的一个标记接口,用于实现对象的序列化。当一个类实现了这个接口,...
Java对象序列化与反序列化是Java编程中重要的概念,主要应用于数据持久化、网络传输以及存储等场景。本文将详细解析这两个概念及其在实际应用中的实现方式。 **一、Java对象序列化** 1. **定义**: Java对象序列化...
在Java编程语言中,序列化和反序列化是两种重要的技术,它们允许我们将对象的状态转换为字节流,以便存储到磁盘上或通过网络进行传输。这些技术在处理持久化数据、对象缓存以及跨进程通信(如RMI - 远程方法调用)时...
这一过程包括两个主要步骤:对象的序列化(将对象转换为字节流)和反序列化(将字节流恢复为对象)。下面我们将深入探讨Java序列化的概念、作用、实现方式以及相关应用。 1. **序列化概念** - Java序列化是Java...
Java反序列化是一种将已...总之,Java反序列化利用是一个复杂的安全问题,需要开发者对序列化和反序列化过程有深入的理解,以及对潜在的安全风险保持警惕。通过了解这些知识点,可以更好地保护应用程序免受此类攻击。
Java序列化是Java平台中的一种持久化机制,它允许对象的状态被转换成字节流,以便存储、网络传输或在不同时间点恢复。这个过程被称为序列化,而反向操作称为反序列化。序列化在许多场景下都非常有用,比如在分布式...
Java反序列化是一种将之前序列化的对象状态转换回对象的过程,它是Java平台中持久化数据的一种常见方法。在Java应用程序中,序列化用于保存对象的状态以便稍后恢复,或者在网络传输中将对象从一个系统传输到另一个...
Java反序列化安全漏洞是一种严重的安全威胁,...总之,Java反序列化安全漏洞是一个广泛存在且危害严重的安全问题。只有通过不断的关注安全动态、实施有效的防御措施以及定期更新和打补丁,才能确保Java应用的安全运行。
要序列化一个对象,可以使用`ObjectOutputStream`,反序列化则使用`ObjectInputStream`。虽然简单易用,但效率较低,且序列化的元数据(如类名、字段名)会被包含在字节流中,存在安全风险(如反序列化攻击)。 2. ...