`
Aguo
  • 浏览: 33197 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

自定义ObjectOutputStream,解决追加写入后,读取错误的问题

    博客分类:
  • J2SE
阅读更多
问题情景:

问题描述: 用类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
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);
	}

}


测试方法:
public static void writeObject() throws Exception {
		String filename = "test.txt";
		File f = new File(filename);
		OutputStream os = new FileOutputStream(f, true);
		MyObjectOutputStream moos = MyObjectOutputStream.newInstance(f, os);
		moos.writeObject("abc");
		moos.writeObject(1);
		moos.close();
	}
分享到:
评论
4 楼 Touch_2011 2011-10-21  
楼主讲的真精辟,thank you,学习了
3 楼 mckelvin 2011-03-15  
楼主帮了大忙!十分感谢!
2 楼 jqwu_csu 2010-09-16  
gmizr 写道
将f设为static,多线程使用的时候会出问题啊
writeStreamHeader是在构造函数被调用的,这个问题还真有点麻烦


恩,是的。 当构造多个MyObjectOutputStream 对象时,static file 会出问题,
是否可以用如下解决。


public class AppendObjectOutputStream extends ObjectOutputStream
{

private File file = null;

public AppendObjectOutputStream(File file) throws IOException
{
super(new FileOutputStream(file));
this.file = file;
}


public void writeStreamHeader() throws IOException
{
if(file != null)
{
if(file.length() == 0)
{
super.writeStreamHeader();
}
else
{
super.reset();
}
}
else
{
super.writeStreamHeader();
}

}
}
1 楼 gmizr 2009-07-01  
将f设为static,多线程使用的时候会出问题啊
writeStreamHeader是在构造函数被调用的,这个问题还真有点麻烦

相关推荐

Global site tag (gtag.js) - Google Analytics