站内搜索: 请输入搜索关键词

当前页面: 开发资料首页Java 专题关于ObjectInputStream类的使用问题

关于ObjectInputStream类的使用问题

摘要: 关于ObjectInputStream类的使用问题


import java.util.*;
import java.io.*;

class Test{
public static void main(String [] args)throws Exception{
for(int i = 0; i < 5 ;i++){
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("t.tmp", true));
out.writeObject(new Date());
out.close();
}

ObjectInputStream in = new ObjectInputStream(new FileInputStream("t.tmp"));
for(int i = 0;i < 5;i++){
System.out.println(in.readObject());
}


}
}

上例,通过追加的方式,分5次往统一文件中添加5个Date对象
但读取时,只能读出第一个,之后就抛出异常:
Exception in thread "main" java.io.StreamCorruptedException
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1326)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:339)
at Test.main(Test.java:14)

另外,如果不知道文件中有几个对象
那如何知道什么时候EOF了
本以为readObject返回NULL则EOF
但实际上直接就抛EOFException异常了
难道只能用catch异常来结束循环?


ding


import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;

class Test{
public static void main(String [] args)throws Exception{
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(new File("t.tmp"),true));
for(int i = 0; i < 5 ;i++){
out.writeObject(new Date());
}
out.flush();
out.close();
ObjectInputStream in =
new ObjectInputStream(
new FileInputStream(
new File("t.tmp")));
for(int i = 0;i < 5;i++){
System.out.println(in.readObject());
}
}
}
你把定义输出流放在了循环中,每次都重新创建文件"t.tmp",所以永远只有一条数据。读第2条记录当然会出错了。
好像就是通过捕获异常来判断结束了,但你可以换用其他的流,就用办法判断了。


new FileOutputStream(new File("t.tmp"),true)
后面那个参数 true
就是指定可扩展的


To:bayougeng(红雨)
我这么写只是为了说明问题
实际的情况就是
第一次写完1个对象,读也没问题,试图多读报EOFException
但第二次追加1个对象,再读,第一个没问题,第二个就出错了
像你这样写确实是没问题的
但难道我每次都要全部读出再全部重写文件?

追加的方式写文本没任何问题
就是写对象的时候有问题





使用缺省的serializetion的实现时,一个ObjectOutputStream的构造和一个ObjectInputStream的构造必须一一对应.ObjectOutputStream的构造函数会向输出流中写入一个标识头,而ObjectInputStream会首先读入这个标识头.因此,多次以追加方式向一个文件中写入object时,该文件将会包含多个标识头.所以用ObjectInputStream来deserialize这个ObjectOutputStream时,将产生StreamCorruptedException.一种解决方法是可以构造一个ObjectOutputStream的子类,并覆盖writeStreamHeader()方法.被覆盖后的writeStreamHeader()方法应判断是否为首次向文件中写入object,羰?则调用super.writeStreamHeader();若否,即以追加方式写入object时,则应调用ObjectOutputStream.reset()方法.
我误解了lz的意思。不好意思。上面的说法我没有验证,但我觉得应该是正确的。看来结果可能还是我写的那样,将一个ObjectOutputStream从头用到尾了。


恩,楼上的说对了,每次构造ObjectOutputStream时都回向流中写如4个字节作为标志,每次构造ObjectInputStream都先回向流中读那4个标志字节,你的程序new 了5次ObjectOutputStream所以写了5次那4个字节标志,但你只new 了一次ObjectInputStream,所以只向流中读一次那4个字节,所以读完第一个对象后,流中接下来的4个字节是标志字节,不是对象的序列化信息,所以用再用readObject()会出现StreamCorruptedException异常,你如果在读2~5个对象之前先读四个字节出来,再用ObjectInputStream读对象就可以了,我试过了~


个人认为ObjectInputStream只能对实现了Serializable接口的类的实例化对象进行操作!
是不是可以考虑将new FileOutputStream(new File("t.tmp"))放在一个单独的类中并实现Serializable接口??
未经验证!


学习中。。。


如何“判断是否为首次向文件中写入object”?

hhl417(菜鸟) 的方法直接依赖于JDK的内部实现,一点内部实现改变,程序又要出问题。而这个内部实现,SUN似乎没在API中承诺过,所以这么作长远看不安全吧


再顶一次


↑返回目录
前一篇: 关于JSP中错误页面跳转的问题
后一篇: 如何用 Java 发送 Email 呢?