java对象流,实现追加的方法!
问题描述: 用类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?Java代码 ?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); ?? ? } ???} ?
测试方法:?Java代码 ?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(); ?? ? } ?