这个类特别的特殊,read方法没什么,都是继承下来的,主要是readOBject方法。本文主要以文件流为基础,实现Object流。
可能有以下异常
1.ClassNotFoundException
- 找不到序列化对象的类。
2.InvalidClassException
- 序列化使用的类出了问题。
3.StreamCorruptedException
- 流中的控制信息不一致。
4.OptionalDataException
- 在流中找到基本类型数据而非对象。
5.IOException
- 任何常规的输入/输出相关的异常。
第一个异常,是你类没有实现Serializable这个接口,这是一个空接口,主要就是用于序列化,有这个表示才能序列化。
解决办法:实现接口。
第二个异常,就是你序列化了,用write写到文件中了,但是你修改了这个类的属性(曾或减),你没有实现这个
private static final long serialVersionUID = 1L;属性。
解决办法:添加属性
第三个异常:没遇到过,不知道。
第四个异常:就是你存的都是基本类型,你读的时候readObject 不行。
解决办法:readint或者什么,用基本类型读取。或者写的时候用Integer等包装类。
第五个异常:太复杂了,什么文件没找到,什么文件不可读,io中断等等,有时间具体说一下。
第六个异常:第七个异常今天的重点,下面仔细说一下,不是一两句能说完的。
先说下ObjectInputstream 1,说下工作机理,2,是可能遇到问题的一种情况,3是网上所说循环读取序列化数据的解决办法。在往下是异常解决办法。
1.他的访问格式是:匹配的数据。
比如:你可以找Date类型,找int类型,而他们不是顺序的存放进去。系统会匹配出来这些东西。
2.不能为空,它是一个反序列化,没有东西的时候会抛出异常就是EOF异常,这种异常。
解决方法:用一个文件流先访问如果为-1就不实例化ObjectInputStream
检查-1,就是看里面有没有东西,不能保证里面是什么,要是一个不是序列化的文件,那也没用,你只能在异常处理中,处理一下了。
3.循环读取问题:因为你是结束不了的。你想说-1结束,那怎么可能int不包括-1,吗;用null结束也不行他自己是没有提供的,所以会报EOF(读到末尾异常)
这个问题有两种解决方式:
One:就是假如一个结束标记符,我假设的null,建议你也假设null
代码如下:
publicstatic void main(String[]args) {
new TRead().write();
new TRead().read();
}
publicvoid read() {
ObjectInputStreamois=null;
try {
ois = new ObjectInputStream(new FileInputStream("D:/a.txt"));
Objectobj=null;
//循环读取,直到读取到自定义结束标示位置
while((obj=ois.readObject())!=null){
TUsertuser= (TUser)obj;
System.out.println(tuser.getAge());
}
}catch(FileNotFoundExceptione) {
e.printStackTrace();
}catch(IOExceptione) {
System.out.println("沒有文件");
}catch(ClassNotFoundExceptione) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if (ois !=null)
try {
ois.close();
}catch(IOExceptione) {
e.printStackTrace();
}
}
}
publicvoid write() {
ObjectOutputStreamoos=null;
try {
oos = new ObjectOutputStream(new FileOutputStream("D:/a.txt"));
TUsertuser2=newTUser();
tuser2.setAge(6);
tuser2.setName("wuliao");
TUsertuser=newTUser();
tuser.setAge(5);
tuser.setName("wuliao");
//添加对象
oos.writeObject(tuser);
oos.writeObject(tuser2);
oos.writeObject(tuser);
oos.writeObject(tuser2);
oos.writeObject(tuser);
oos.writeObject(tuser2);
//重点:::::::添加结束标示
oos.writeObject(null);
}catch(FileNotFoundExceptione) {
e.printStackTrace();
}catch(IOExceptione) {
e.printStackTrace();
}finally{
if (oos !=null)
try {
oos.close();
}catch(IOExceptione) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Two:第二种解决办法:装到一个集合中去
publicstaticvoidmain(String[]args){
new TRead2().write();
new TRead2().read();
}
publicvoid read() {
ObjectInputStreamois=null;
try {
ois = new ObjectInputStream(new FileInputStream("D:/a.txt"));
Objectobj=null;
//读取list对象
obj=ois.readObject();
@SuppressWarnings("unchecked")
List<TUser>list= (List<TUser>)obj;
System.out.println(list.get(0).getAge());
}catch(FileNotFoundExceptione) {
e.printStackTrace();
}catch(IOExceptione) {
System.out.println("沒有文件");
}catch(ClassNotFoundExceptione) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if (ois !=null)
try {
ois.close();
}catch(IOExceptione) {
e.printStackTrace();
}
}
}
publicvoid write() {
ObjectOutputStreamoos=null;
try {
oos = new ObjectOutputStream(new FileOutputStream("D:/a.txt"));
//构建list 对象
TUsertuser2=newTUser();
tuser2.setAge(6);
tuser2.setName("wuliao");
TUsertuser=newTUser();
tuser.setAge(5);
tuser.setName("wuliao");
List<TUser>list=newArrayList<TUser>();
list.add(tuser);
list.add(tuser2);
//得到list,並写入到对象文件中
oos.writeObject(list);
}catch(FileNotFoundExceptione) {
e.printStackTrace();
}catch(IOExceptione) {
e.printStackTrace();
}finally{
if (oos !=null)
try {
oos.close();
}catch(IOExceptione) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
1.最不可思议的问题,这个对象会检查你的文件是不是符合他们的要求。抛出StreamCorruptedException
//str是个字符串参数
fis =new FileInputStream(str);
if (fis.read() == -1)
return;
in = new ObjectInputStream(fis);
这就会检查出错
in = new ObjectInputStream(new FileInputStream(str));
这就不会出错。
我猜想是这样,他检测头信息的时候不是检测文件而是检测fis对象的序列化值,这个值没有变,所以就不行。