实现InputStream的序列化

实现InputStream的序列化

June 12, 2018

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;

对于这个场景,序列化的类只需实现writeObject与readObject这两个方法就足够了。readObjectNoData这个方法只是在特定的情况下才需要用,对于简单的应用场景来说,可以不用实现。

为了实现输入流的序列化,需要新建一个继承于Serializable接口的实体类,序列化的时候将输入流转成字节数组(writeObject方法),反序列化则将字节流转成输入流(readObject方法)。值得注意的是,这里要用到transient关键字来修饰不可序列化的InputStream私有字段。

示例代码:
```java
public class SerializableStream implements Serializable {
    private final static int LENGTH = 1024;
    private transient InputStream inputStream;

    public SerializableStream(InputStream is) {
        this.inputStream = is;
    }

    public InputStream getInputStream() {
        return inputStream;
    }

    private void writeObject(ObjectOutputStream oos) throws Exception {
        oos.defaultWriteObject();
        
        byte[] buff = new byte[LENGTH];
        int tmp;
        while ((tmp = inputStream.read(buff, 0, LENGTH)) != -1) {
            oos.write(buff, 0, tmp);
        }
    }

    private void readObject(ObjectInputStream ois) throws Exception {
        ois.defaultReadObject();
        
        byte[] buf = new byte[LENGTH];
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        int tmp;
        while ((tmp = ois.read(buf, 0, LENGTH)) != -1) {
            bos.write(buf, 0, tmp);
        }

        inputStream = new ByteArrayInputStream(bos.toByteArray());
    }
}
最后更新于