黑马程序员技术交流社区

标题: ObjectOutputStream问题? [打印本页]

作者: 黑马薛有义    时间: 2011-7-19 09:43
标题: ObjectOutputStream问题?
若通过ObjectOutputStream向一个文件中多次以追加方式写入object,为什么用ObjectInputStream读取这些object时会产生StreamCorruptedException?
作者: 匿名    时间: 2011-7-19 11:08
因为看不到你的程序,不知道你的程序时具体怎么写的。你是不是忘了ObjectInputStream要先传个 InputStream给他才行,
FileInputStream in=new FileInputStream ("d:/a.txt");
ObjectInputStream  ips=new  ObjectInputStream(  in );
ips.readObject();
作者: 匿名    时间: 2011-7-19 17:10
•  ObjectInputStream 和ObjectOutputStream又被称为对象流。
•  对于对象流的操作:
    |-  在序列化对象时要一次性写入完毕。
    因为:
    |-  使用对象流写入时,会先写入一个头部,然后写入数据,最后加上结束符号。
    |-  如果使用追加方式写入的话,那新数据就会在文件末尾继续向下写入。
    |-  但是在读取时只会读到第一个结束符就停止,后来再次写入的数据就根本都不到了。
观察如下代码:[code=java]package org.cxy.test;

import java.io.*;
public class Demo{
        public static void main(String[] args) throws Exception{
                ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(new File("D:/a.txt"),true));
                out.writeObject("第一个对象!");
                out.writeObject("第二个对象!");
                out.close();
                out = new ObjectOutputStream(new FileOutputStream(new File("D:/a.txt"),true));
                out.writeObject("第三个对象!");
                out.writeObject("第四个对象!");
                out.close();
                ObjectInputStream in = new ObjectInputStream(new FileInputStream(new File("D:/a.txt")));
                System.out.println(in.readObject());
                System.out.println(in.readObject());
                in.close();
        }
}[/code]程序执行的时候,永远只会读取到咱们序列化的前两个对象,即String类型的 “第一个对象!”和“第二个对象!”。
也许您会说,“你胡说,你程序序列化了4个String对象,但是你却只读了前两个对象,当然读不到后边的对象了啊”。
事实真是如此吗? 若是用下面的代码,就会出错:[code=java]package org.cxy.test;

import java.io.*;
public class Demo{
        public static void main(String[] args) throws Exception{
                ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(new File("D:/a.txt"),true));
                out.writeObject("第一个对象!");
                out.writeObject("第二个对象!");
                out.close();
                out = new ObjectOutputStream(new FileOutputStream(new File("D:/a.txt"),true));
                out.writeObject("第三个对象!");
                out.writeObject("第四个对象!");
                out.close();
                ObjectInputStream in = new ObjectInputStream(new FileInputStream(new File("D:/a.txt")));
                System.out.println(in.readObject());
                System.out.println(in.readObject());
                System.out.println(in.readObject());
                System.out.println(in.readObject());
                in.close();
        }
}[/code]现在按照您的要求,我读了4个对象进来,但是程序执行时,出现什么问题?[code=java]Exception in thread "main" java.io.StreamCorruptedException: invalid stream header: ACED2005
        at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
        at java.io.ObjectInputStream.<init>(Unknown Source)
        at org.cxy.test.Demo.main(Demo.java:14)[/code]吼吼,问题解决了,之所以出现这个异常,是因为,在反序列化读取时只会读到第一个结束符就停止,读到第一个结束符后程序就认为之后没有数据了,若仍然继续读,就会抛StreamCorruptedException异常了。这个异常和EOFException颇为相似。
因此,以后别用追加的方式序列化对象。要一次性序列化完所有的对象后,再关闭ObjectOutputStream 。

另外,补充一下:
•  对象的属性会被递归序列化的。
    |-  对象所有属性必须都实现了Serializable接口,特别是当有些属性本身也是对象的时候,要尤其注意这一点。
•  网络中传递对象必须实现序列化。
•  静态属性不会被序列化的。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2