java.io.StreamCorruptedException: invalid type code: AC

问题情景:  

问题描述:  用类ObjectOutputStream向文件写读对象时,碰到一个问题:新建一个文 
  件,用输出流ObjectOutputStream向文件连续写几个对象,关闭输出流,然 
  后读取,这些对象都可以读出;这时在向该文件增加对象,新写的对象就读不出了,不知什么原因?请教了! 
  
  问题出现的原因: ObjectOutputStream建立后第一次写入一个对象时, 会在对象数据前写入一些标志的数据“AC ED 
  00 05”(用ultraEdit打开),应该是流相关的信息。当你关闭 
  ObjectOutputStream后再重新打开往文件里面写对象时(append方式),就会再一次把“AC ED 00 
  05”写入文件,而这些信息并不是你写入对象的数据,所以当你用ObjectInputStream来读取对象时,流会将除第一个“AC ED 00 
  05”以外的数据当作各个对象的数据,造成无法解析,所以读取时有一个java.io.StreamCorruptedException出现。 
  这个可以通过编辑Info.dat来验证,只要将“AC ED 00 05”删除(第一个“AC ED 00 05”保留)就可以正常读出后来加入的对象。 
  给出一个比较笨的解决方法: 在以后要添加新的对象到Info.dat时,将里面原有的对象读出放入ArrayList中,清空文件,再将对象集一次写入。 
  
   尝试解决办法:  那个“AC ED 00 05”是 
  ObjectOutputStream.writeSystemHeader()写进去的,你可以继承ObjectOutputStream类,覆盖这个方法。 
  在你自己的writeSystemHeader()里判断是不是第一次写入一个文件,如果是向一个文件大小不为零的文件追加的话,就调用 
  super.reset(),如果是第一次写这个文件,不是追加,就调用super.writeSystemHeader() 

自定义类MyObjectOutputStream 

package com.bjsxt.io.obj;

import java.io.*;

public class MyObjectOutputStream extends ObjectOutputStream {
	// 定义成静态的好处
	private static File f;

	/**
	 * 初始化静态文件对象,并返回类对象
	 * 
	 * @param file
	 *            文件对象,用于初始化静态文件对象
	 * @param out
	 *            输出流
	 * @return MyObjectOutputStream
	 * @throws IOException
	 */
	public static MyObjectOutputStream newInstance(File file, OutputStream out) throws IOException {
		f = file;// 本方法最重要的地方:构建文件对象,是两个文件对象属于同一个
		return new MyObjectOutputStream(out, f);
	}
	@Override
	protected void writeStreamHeader() throws IOException {
		if (!f.exists() || (f.exists() && f.length() == 0)) {
			super.writeStreamHeader();
		} else {
			super.reset();
		}

	}

	public MyObjectOutputStream(OutputStream out, File f) throws IOException {
		super(out);
	}

}

对象输出类

package com.bjsxt.io.obj;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;

/**
 * 序列化:将对象保存到磁盘内
 *    1. 如何实现序列化?
 *     类实现接口    会产生  version ID   
 *        default 
 *       	动态生成   属性值不同  ID也不同
 *     		public class Student implements Serializable
 *    2.某个属性不想被序列化
 *        属性前+static 
 *        transient   
 * 
 * 反序列化:读取到磁盘内的对象数据
 * @author Mr.Gao
 *
 */
public class ObjectOutPutStreamTest {
	@SuppressWarnings("resource")
	public static void main(String[] args) throws IOException {
		//1.新建流对象
		//节点流
		File file = new File("D:\\object.txt");
		OutputStream os = new FileOutputStream(file,true);
		//缓冲流
		BufferedOutputStream bos = new BufferedOutputStream(os);
		//处理流
		//ObjectOutputStream oos = new ObjectOutputStream(bos);
		   MyObjectOutputStream oos = MyObjectOutputStream.newInstance(file, bos);  
		//2.写出数据
		Student s1 = new Student("李白", 34, 99);
		Student s2 = new Student("杜甫",32,89);
		System.out.println(file.length());
		  
		
		oos.writeObject(s1);
		oos.writeObject(s2);
		System.out.println("写出完毕");
		//3.关流
		oos.close();
		
		
		
	}
}

读取对象流:

package com.bjsxt.io.obj;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

/**
 * 反序列化: 读取磁盘上的对象 反序列化时 反序列化的ID 必须与序列化的ID一致
 * 
 * @author Mr.Gao
 */
public class ObjectInputStreamTest {
	public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
		// 创建对象输入流对象
		// 读取对象
		ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream("D:\\object.txt")));
		Object readObject = null;

		readObject = ois.readObject();
		// readObject = ois.readObject();
		System.out.println(readObject);

		System.out.println(ois.readObject());
		System.out.println(ois.readObject());
		// 关流
		ois.close();
	}
}

实体类

package com.bjsxt.io.obj;

import java.io.Serializable;

public class Student implements Serializable{
	
 	private static final long serialVersionUID = 21L;
	private  String name;
	private int age;
	//private int id;
	public Student(String name, int age, double score) {
		super();
		this.name = name;
		this.age = age;
		this.score = score;
	}
	public Student() {
		super();
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public double getScore() {
		return score;
	}
	public void setScore(double score) {
		this.score = score;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + ", score=" + score + "]";
	}
}


  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值