实现InputStream的序列化
InputStream本身是不支持序列化的,但是在实际开发的过程中有时会需要将输入流通过socket传输,比如RMI的远程调用。
在Serializable的Java文档文档中有下面的描述:
Classes that require special handling during the serialization and deserialization process must implement special methods with these exact signatures:
private void writeObject(java.io.ObjectOutputStream out) throws IOException
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;
private void readObjectNoData() throws ObjectStreamException;
1
2对于这个场景,序列化的类只需实现writeObject与readObject这两个方法就足够了。readObjectNoData这个方法只是在特定的情况下才需要用,对于简单的应用场景来说,可以不用实现。
3
4为了实现输入流的序列化,需要新建一个继承于Serializable接口的实体类,序列化的时候将输入流转成字节数组(writeObject方法),反序列化则将字节流转成输入流(readObject方法)。值得注意的是,这里要用到transient关键字来修饰不可序列化的InputStream私有字段。
5
6示例代码:
7```java
8public class SerializableStream implements Serializable {
9 private final static int LENGTH = 1024;
10 private transient InputStream inputStream;
11
12 public SerializableStream(InputStream is) {
13 this.inputStream = is;
14 }
15
16 public InputStream getInputStream() {
17 return inputStream;
18 }
19
20 private void writeObject(ObjectOutputStream oos) throws Exception {
21 oos.defaultWriteObject();
22
23 byte[] buff = new byte[LENGTH];
24 int tmp;
25 while ((tmp = inputStream.read(buff, 0, LENGTH)) != -1) {
26 oos.write(buff, 0, tmp);
27 }
28 }
29
30 private void readObject(ObjectInputStream ois) throws Exception {
31 ois.defaultReadObject();
32
33 byte[] buf = new byte[LENGTH];
34 ByteArrayOutputStream bos = new ByteArrayOutputStream();
35 int tmp;
36 while ((tmp = ois.read(buf, 0, LENGTH)) != -1) {
37 bos.write(buf, 0, tmp);
38 }
39
40 inputStream = new ByteArrayInputStream(bos.toByteArray());
41 }
42}