将对象写到数组中,为啥会出现 java.io.EOFException 异常呢?代码如下:
public class TestObjectStream {
public static void main(String[] args) throws ClassNotFoundException, IOException {
read(ser());
}
//序列化
public static byte[] ser() throws IOException{
Student stu = new Student("张三", 12);
byte[] dest = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(baos));
oos.writeObject(stu);
dest = baos.toByteArray();
baos.close();
oos.close();
return dest;
}
//反序列化
public static void read (byte[] src) throws IOException, ClassNotFoundException{
ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new ByteArrayInputStream(src)));
Object readObject = ois.readObject();
if(readObject instanceof Student){
System.out.println(((Student) readObject).name);
System.out.println(((Student) readObject).age);
}
ois.close();
}
}
class Student implements Serializable{
public transient String name;
public int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
}
麻烦各位给看看。
------解决思路----------------------
16行的toByteArray应放在19行的oos.close后面,并且baos.close()不恰当,应删去。
原因:
1. BufferedOutputStream有一个缓冲区,当外层向他写入的字节多于缓冲区大小后,它才向内层的流写入一次数据。一个对象的信息比较小,不足以引起它的刷新,故数据必须要在缓冲流被flush或close后才能被写入内层流。因此toByteArray的调用需要在oos流关闭(外层流close时会调用内层流的close方法)后才可(此时流中才有东西)。
2.baos会随着oos的关闭自动关闭,不需要手动关闭,即使想手动关闭也应该在外层流关闭之后(如果你把baos换成一个文件输出流,现在的代码就会报错,因为缓冲流会在关闭时尝试向一个已关闭的流中写数据)。
------解决思路----------------------
楼上解释的很清晰了...
建议写代码的时候,手动flush...
------解决思路----------------------
手动flush容易降低效率。只有当一些信息要发送的很及时的时候,建议手动刷新flush。(如socket编程发送消息的时候)其他的时候不建议手动刷新。
------解决思路----------------------
第一个问题:因为ByteArrayOutputStream流的close方法没有实质性的作用(在Doc里面有写到的)。
第二个问题:(1)对的,有些流没有缓冲区,flush没有用;有些流的flush实际上调用了底层(os或硬件)。flush的要求中没有保证它一定要起效,只需要保证调用flush后没有滞留的数据就可以,即本来就不会滞留数据的流的flush基本没用。
(2)其实还有一些网络流等等的close方法是有效的。。探究他们到底是否有效的方法貌似只能查看源码了,但这并没有什么用——每次用完了流关闭它就可以了,不管它到底是否有效。