java.io.StreamCorruptedException: invalid type code: AC解决办法

问题描述:

在向一个文件写入可序列化对象时,每次只想向文件的末尾添加一个可序列化的对象,于是使用了FileOutputStream(文件名,true)间接的构建了ObjectOutputStream流对象,在向外读数据的时候第一次运行的时候不会报错,在第二次就会报java.io.StreamCorruptedException: invalid type code: AC错误。

原因:

在一个文件都有一个文件的头部和文件体。由于对多次使用FileOutputStream(文件名,true)构建的ObjectOutputStream对象向同一个文件写数据,在每次些数据的时候他都会向这个文件末尾先写入header在写入你要写的对象数据,在读取的时候遇到这个在文件体中的header就会报错。导致读出时,出现streamcorrput异常。

解决办法:所以这里要判断是不是第一次写文件,若是则写入头部,否则不写入。

代码示例:

1.ObjectAppendOutputStream.java文件

class ObjectAppendOutputStream extends ObjectOutputStream {
	
	public ObjectAppendOutputStream() throws IOException {
		super();
	}
	
	public ObjectAppendOutputStream(OutputStream out) throws IOException {
		super(out);
	}
	
	@Override
	protected void writeStreamHeader() throws IOException {
		return;
	}
}


2、ObjectToFileUtil

public class ObjectToFileUtil {
	
	public static <T> void write(String path, T t) {
		List<T> ts = new ArrayList<T>();
		ts.add(t);
		write(path, ts);
	}
	
	public static <T> void write(String path, List<T> ts) {
		ObjectOutputStream out = null;
		try { // 判断文件大小并调用不同的方法
			File file = new File(path);
			
			if (file.exists() == false) {
				file.createNewFile();
			}
			
			FileOutputStream fos = new FileOutputStream(file, true);
			if (file.length() < 1) {
				out = new ObjectOutputStream(fos);
			} else {
				out = new ObjectAppendOutputStream(fos);
			}
			// 判断文件大小并调用不同的方法
			for (T t : ts) {
				out.writeObject(t);
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			try {
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static <T> T readOne(String path){
		List<T> temp = read(path);
		if(temp ==null || temp.size() == 0 ){
			return null;
		}
		
		return temp.get(0);
	}
	
	public static <T> List<T> read(String path){
		List<T> result = new ArrayList<T>();
		ObjectInputStream in = null;
		try {
			in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(path)));
			Object temp = null;
			while ((temp = in.readObject()) != null) {
				T t = (T)temp;
				result.add(t);
			}
		} catch (EOFException e) {
			
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return result;
	}
	
	
	
	public static void main(String[] args) {
		List<User> list = new ArrayList<User>();
		list.add(new User("admin", "admin", "123", 1));
		list.add(new User("zhang", "zhang", "123", 0));
		list.add(new User("san", "san", "123", 0));
		String path = "d://abcd.data";
		
		ObjectToFileUtil.write(path, list);
		ObjectToFileUtil.write(path, new User("tian", "tian", "123", 0));
		List<User> users = ObjectToFileUtil.read(path);
		for(User u:users){
			System.out.println(u.name);
		}
	}
}


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值