gpt4 book ai didi

Java - 使用 nio 读取对象

转载 作者:搜寻专家 更新时间:2023-10-31 19:35:42 25 4
gpt4 key购买 nike

在传统的阻塞线程服务器中,我会做这样的事情

class ServerSideThread {

ObjectInputStream in;
ObjectOutputStream out;
Engine engine;

public ServerSideThread(Socket socket, Engine engine) {
in = new ObjectInputStream(socket.getInputStream());
out = new ObjectOutputStream(socket.getOutputStream());
this.engine = engine;
}

public void sendMessage(Message m) {
out.writeObject(m);
}

public void run() {
while(true) {
Message m = (Message)in.readObject();
engine.queueMessage(m,this); // give the engine a message with this as a callback
}
}
}

现在,可以预期该对象非常大。在我的 nio 循环中,我不能简单地等待对象通过,我的所有其他连接(工作负载要小得多)都将等待我。

在连接告诉我的 nio channel 它已准备好之前,我如何才能只收到连接具有整个对象的通知?

最佳答案

您可以将对象写入 ByteArrayOutputStream,从而允许您在发送对象之前给出长度。在接收端,在尝试解码之前读取所需的数据量。

但是,您可能会发现在 Object*Stream 中使用阻塞 IO(而不是 NIO)更加简单和高效


编辑这样的东西

public static void send(SocketChannel socket,  Serializable serializable) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for(int i=0;i<4;i++) baos.write(0);
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(serializable);
oos.close();
final ByteBuffer wrap = ByteBuffer.wrap(baos.toByteArray());
wrap.putInt(0, baos.size()-4);
socket.write(wrap);
}

private final ByteBuffer lengthByteBuffer = ByteBuffer.wrap(new byte[4]);
private ByteBuffer dataByteBuffer = null;
private boolean readLength = true;

public Serializable recv(SocketChannel socket) throws IOException, ClassNotFoundException {
if (readLength) {
socket.read(lengthByteBuffer);
if (lengthByteBuffer.remaining() == 0) {
readLength = false;
dataByteBuffer = ByteBuffer.allocate(lengthByteBuffer.getInt(0));
lengthByteBuffer.clear();
}
} else {
socket.read(dataByteBuffer);
if (dataByteBuffer.remaining() == 0) {
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(dataByteBuffer.array()));
final Serializable ret = (Serializable) ois.readObject();
// clean up
dataByteBuffer = null;
readLength = true;
return ret;
}
}
return null;
}

关于Java - 使用 nio 读取对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5862971/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com