Java中对象输出流问题

来源:互联网 发布:js splice 数组 编辑:程序博客网 时间:2024/06/06 05:45

对象输出流问题:

怎样能连续向文件中添加对象,并且可以从文件中循环读取出对象?

错误的情况:连续多次调用oos.writeObject(user)向文件中写入对象,然后这样while((user=(User)ois.readObject())!=null)循环取出对象

出现这种情况的解释:ObjectOutputStream建立后第一次写入一个对象时, 会在对象数据前写入一些标志的数据“ACED0005”。当你关闭ObjectOutputStream后再重新打开往文件里面写对象时(append方式),就会再一次把“ACED0005”写入文件,而这些信息并不是你写入对象的数据,所以当你用ObjectInputStream来读取对象时,流会将除第一个“ACED0005”以外的数据当作各个对象的数据,造成无法解析,所以读取时有一个java.io.StreamCorruptedException异常出现:java.io.StreamCorruptedException: invalid type code: AC

解决办法:那个“AC ED 00 05”是ObjectOutputStream.writeSystemHeader()写进去的,你可以继承ObjectOutputStream类,覆盖这个方法。在你自己的writeSystemHeader()里判断是不是第一次写入一个文件,如果是向一个文件大小不为零的文件追加的话,就调用super.reset(),如果是第一次写这个文件,不是追加,就调用super.writeSystemHeader()

自定义类MyObjectOutputStream:

public classMyObjectOutputStream extends ObjectOutputStream {

         //定义成静态的好处 

    private static File f; 

    /*

     * 初始化静态文件对象,并返回类对象

     * @param file 文件对象,用于初始化静态文件对象

     * @param out 输出流

     */ 

    public static  MyObjectOutputStream newInstance(File file,OutputStream out)throws IOException { 

        f= file;//本方法最重要的地方:构建文件对象,是两个文件对象属于同一个 

        return new MyObjectOutputStream(out,f); 

    } 

 

    @Override 

    protected void writeStreamHeader() throwsIOException { 

        if (!f.exists() || (f.exists()&& f.length() == 0)) { 

            super.writeStreamHeader(); 

        } else { 

            super.reset(); 

        } 

    } 

 

    public MyObjectOutputStream(OutputStreamout, File f) throws IOException { 

        super(out); 

    } 

}

测试方法:

         public static void WriteNode(FileNodenode){

                   try {

                            File file = newFile("F:\\Tree.txt");

                            FileOutputStreamfout = new FileOutputStream(file, true);

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

                            MyObjectOutputStreamoos = MyObjectOutputStream.newInstance(file, fout);

                            oos.writeObject(node);

                            oos.close();

                   }catch (Exception e) {

                            e.printStackTrace();

                   }

         }

通过上面的处理办法向文件中写入数据,当再用while((user=(User)ois.readObject())!=null)循环取对象时就不会抛出java.io.StreamCorruptedException: invalid type code: AC异常了。

 

第一种:

添加多个对象:可以将要添加的对象封装到集合中去,比如List,然后将list对象写入文件oos.writeObject(list)。

要注意new FileOutputStream(file, true);  //true表示要在文件内容后面追加内容,不会造成覆盖问题。

读取对象:可以取出List<User> list =(List<User>)ois.readObject(),然后用Iterator迭代List集合取出所有对象。

0 0