发送压缩对象的Java套接字

时间:2018-10-13 05:51:44

标签: java sockets

我想压缩我的可序列化对象并通过java套接字发送它们。 可序列化的对象:

public class MyObject implements Serializable {

private int id;
private String name;
//getter,setter and equal, hashCode, toString methods

}



public class Sender {

private Socket clientSocket;

public void send(MyObject obj){
GZIPOutputStream gzipOut = new GZIPOutputStream(clientSocket.getOutputStream());
ObjectOutputStream objectOut = new ObjectOutputStream(gzipOut);
objectOut.writeObject(obj);
}
}



public class Receiver {

private Socket serverSocket;

public MyObject receive(){
GZIPInputStream gzipIn = new GZIPInputStream(serverSocket.getInputStream());
ObjectInputStream objectIn = new ObjectInputStream(gzipIn);
return (MyObject) objectIn.readObject();
}

}

这会引发ZipException:接收方不是GZIP格式。

我不会关闭流和套接字,因为需要使用相同的流和套接字(出于性能考虑)发送多个对象

1 个答案:

答案 0 :(得分:0)

ObjectStream是可用的最详细的序列化格式之一。几乎任何其他序列化都会对大小更好。必须刷新ObjectStream才能发送所有数据,并且在一个连接中不能发送多个流,这使得每个连接仅发送一个对象的效率很低。

压缩流最适用于大量数据,当您尝试将其应用到几个字节时,结果更大而不是更小。必须清除压缩流才能读取。

  

需要使用相同的流和套接字发送多个对象(出于性能考虑)

这意味着您必须保留GZIP /对象流。每个视频流最多只能使用一个。

public class ObjectSocket implements Closeable {
    private final Socket socket;
    private final ObjectOutputStream output;
    private final ObjectInputStream input;

    public ObjectSocket(Socket socket) throws IOException {
        this.socket = socket;
        this.output = new ObjectOutputStream(new DeflaterOutputStream(socket.getOutputStream()));
        this.input = new ObjectInputStream(new InflaterInputStream(socket.getInputStream()));
    }

    public void send(Serializable obj) throws IOException {
        output.writeObject(obj);
        output.reset();
        output.flush();
    }

    public <T extends Serializable> T receive() throws IOException, ClassNotFoundException {
        return (T) input.readObject();
    }

    @Override
    public void close() throws IOException {
        output.close();
        input.close();
        socket.close();
    }
}