从文件中读对象时抛出的异常:java.io.StreamCorruptedException: unexpected block data

yigeyigeyige 2005-01-02 09:29:19
如题:
这是书上的一个例子:
//写对象到文件中。
private void saveSketch(File outFile) {
try {
ObjectOutputStream out = new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream(outFile)));
out.writeObject(m_model); // Write the sketch to the
// stream
out.close(); // Flush & close it
} catch(IOException e) {
System.err.println(e);
}
}
读对象到文件中:
public void insertModel(String filePath){
File inFile = new File(filePath);
try {
ObjectInputStream in = new ObjectInputStream(
new BufferedInputStream(
new FileInputStream(inFile)));
m_model = (SketchModel)in.readObject();
in.close();
} catch(Exception e) {
System.out.println(e);
}
}
就这样两段程序,我用书上的工程编译后,执行正常,可以将对象保存在文件中并读出来。把这段代码拷到我自己的工程中,也可以用。
问题在于:书上的工程产生的文件,用我自己的工程无法读出对象:报java.io.StreamCorruptedException: unexpected block data。
而用我自己的工程创建的对象,用书上的工程读不出来,报:
java.lang.ClassNotFoundException
不知是何原因。
...全文
1953 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
yigeyigeyige 2005-01-05
  • 打赏
  • 举报
回复
XML看来是正道,虽然复杂了些。比如前些天想把一棵树写进XML,大致也像楼上的写法,但死活就是出错。最后还是用了递归来写XML。有机会可以研究一下。
其实我也并没有和别公司交换数据的需要,只是正好发现了这个问题而已,想看看大家都是怎么处理系列化的。
感谢大家对我的帖子的支持,希望今后继续,结贴了。
梦想家起飞 2005-01-04
  • 打赏
  • 举报
回复
既然你们所要的文件只是为了和别的公司交换数据用,那么为什么不用XML呢?中性的XML天生就是数据交换的好载体。

举一个简单的例子:
--------------------------------
XMLEncoder xmlencd =
new XMLEncoder(
new BufferedOutputStream(
new FileOutputStream( "c:/myinf.xml" ) ) );

xmlencd.writeObject( myinf ); //myinf就是你要系列化的对象
xmlencd.close();
--------------------------------

如果你要系列化的对象包含的信息都可以转换为字符文本信息,那么用上面的代码就可以直接的系列化对象了,如果包含非字符文本的二进制或多媒体数据,那就需要一套编码解码机制将数据在二进制和字符数据之间转换了。

你的程序要实现的功能同样是对象的系列化,用xml多简单?而且兼容性和扩展性也要强的多呢。
yigeyigeyige 2005-01-04
  • 打赏
  • 举报
回复
嗯,试了一下。文件头倒是一样了,不过又发现,把element写文件时,比如Circel类,在文件里还会有:nt2000..picedit..Element$Circel这样的工程..包..类$内置类这样的标记。虽然没在另一个工程里试,不过估计还是一样。在Circel的writeObject中,只写了:out.writeDouble(circle.width);读时:double width = in.readDouble();
circle = new Ellipse2D.Double(0,0,width,width);
不知要怎处理了,好在对手头工程没什么影响。
贴子再放一、二天吧,看看大家还有什么意见,到时一定结贴。
谢谢。
vongood 2005-01-03
  • 打赏
  • 举报
回复
gz
mrwest 2005-01-03
  • 打赏
  • 举报
回复
是不是能修改一下,改成写那个elementList对象,而不写整个SketchModel?
我上星期刚做了个模拟考试系统,我们老师布置的项目,用的是tableModel,存储数据用的是Vector,我是把Vector的对象往文件里边写,同样是写对象。
梦想家起飞 2005-01-03
  • 打赏
  • 举报
回复
既然是作用完全相同的类,那么为什么还要用两个呢??只用一个类,然后重用它不就行了?
lizzz 2005-01-03
  • 打赏
  • 举报
回复
既然两个类所属的包都不一样,怎么能说这两个类是一样的呢?
如果是一样的,那么a.A.java == b.A.java,那不得天下大乱:)
yigeyigeyige 2005-01-03
  • 打赏
  • 举报
回复
1、java.lang.ClassNotFoundException是运行时开发环境抛出的,编译绝对没有问题。
2、“你在写入文件的时候流好象用错了,具体你看下书上用的什么流。”用的流肯定没问题,因为我用各自的程序生成的文件存储和读取各自的对象,都是正常的。
3、我要写的对象是SketchModel类,当然实现了Serializable接口。
4、大家好象并没有完全明白我的意思:两个程序独立工作都是正常的,对象可以被存储和读回,但两个程序产生的文件无法被对方读取,虽然存储的对象数据结构和读写文件的方法是一模一样的。
5、今天对比了一下两个程序生成的文件,发现其唯一的区别是:一个文件头为:..sr..nt2000..picedit..sktechmodel,另一个为::..sr..sktechmodel,后面是一样的。前面的nt2000..picedit是我的工程名称和包名称,后面一个不在包里头。
yigeyigeyige 2005-01-03
  • 打赏
  • 举报
回复
补充:
public void add(Element element) 中的Element较长,就不贴了,它是一个保存基本图形单元的类,如:Line,保存其颜色、长度、位置等信息。
yigeyigeyige 2005-01-03
  • 打赏
  • 举报
回复
SketchModel:
import java.util.Observable;
import java.util.LinkedList;
import java.util.Iterator;
import java.io.Serializable;

class SketchModel extends Observable implements Serializable {
public boolean remove(Element element) {
boolean removed = elementList.remove(element);
if(removed) {
setChanged();
notifyObservers(element.getBounds());
}

return removed;
}

public void add(Element element) {
elementList.add(element);
setChanged();
notifyObservers(element.getBounds());
}

public Iterator getIterator() {
return elementList.listIterator();
}

protected LinkedList elementList = new LinkedList();
}
mrwest 2005-01-03
  • 打赏
  • 举报
回复
如果没记错的话,我记得好像你要写的对象的类一定要实现一个Serializable接口
mrwest 2005-01-03
  • 打赏
  • 举报
回复
顺便问一下,你这个SketchModel是继承了哪个model?
mrwest 2005-01-03
  • 打赏
  • 举报
回复
msn: mrwest@133sh.com
email: mrwest@133sh.com
愿意与老兄你共同研究这个难题:)
yigeyigeyige 2005-01-03
  • 打赏
  • 举报
回复
to:mrwest:
试了,即使是本程序的读写都不行。
mrwest 2005-01-03
  • 打赏
  • 举报
回复
既然文件头部一样,那老兄你试试把他写一样了,首先在每个要进行写入的类当中添一个String 类型的静态成员,比如说
private static final String fileFlag = "XXX_FILE";
然后在你写对象的前一行,也就是
out.writeObject(m_model);
的前面加一行,
out.writeObject(fileFlag);
这样文件头就一样了,

然后,在读取对象的类中,读取对象的语句前面加上
String s = (String) in.readObject();
if(!s.equals(fileFlag)) {
throw new IOException("...");
}
然后再
m_model = (SketchModel)in.readObject();
这样试一下。不知道行不行 :)
yigeyigeyige 2005-01-03
  • 打赏
  • 举报
回复
补充:
m_model = (SketchModel)in.readObject();
这一句即使不做类型转换,写成:Object obj = in.readObject();仍然抛出同样的异常。
yigeyigeyige 2005-01-03
  • 打赏
  • 举报
回复
“既然是作用完全相同的类,那么为什么还要用两个呢??只用一个类,然后重用它不就行了?”,首先,抛开为何要这么使用,我想弄清楚,不能互相读写,是否是因为其所属的包不同?如果是这样的话,比如我公司一个应用的数据文件,现在要让另一个公司的应用能够使用,那么,我除了提供所存属对象的数据结构外,还需要提供什么?需要把类所属的包结构也提供吗?或者说,我公司在开发这个类时要有什么注意事项才能方便地为别人(或公司)提供共享。
我是一初学者,望大家支持。
andy08160819 2005-01-03
  • 打赏
  • 举报
回复
不是写入文件,而是读文件
不好意思
andy08160819 2005-01-03
  • 打赏
  • 举报
回复
java.lang.ClassNotFoundException
没有编译?或者编译不成功!
java.io.StreamCorruptedException: unexpected block data。
你在写入文件的时候流好象用错了,具体你看下书上用的什么流

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧