A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黑马薛有义 黑马帝   /  2011-7-19 09:43  /  3896 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

若通过ObjectOutputStream向一个文件中多次以追加方式写入object,为什么用ObjectInputStream读取这些object时会产生StreamCorruptedException?

评分

参与人数 1技术分 +1 收起 理由
admin + 1 我都没这样干过,加分了

查看全部评分

2 个回复

倒序浏览
黑马网友  发表于 2011-7-19 11:08:07
沙发
因为看不到你的程序,不知道你的程序时具体怎么写的。你是不是忘了ObjectInputStream要先传个 InputStream给他才行,
FileInputStream in=new FileInputStream ("d:/a.txt");
ObjectInputStream  ips=new  ObjectInputStream(  in );
ips.readObject();

评分

参与人数 1技术分 +1 收起 理由
admin + 1 积极参与!!奖

查看全部评分

回复 使用道具 举报
黑马网友  发表于 2011-7-19 17:10:27
藤椅
•  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接口,特别是当有些属性本身也是对象的时候,要尤其注意这一点。
•  网络中传递对象必须实现序列化。
•  静态属性不会被序列化的。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马