实现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}
...