Java nio部分阅读

时间:2013-04-25 14:32:44

标签: java client-server nio partial bytebuffer

我的目标是从客户端向服务器发送不同类型的消息,它将基于文本。我不确定的是如何在这里使用部分读取。我必须确保我得到一个完整的信息,而不是更多。

有没有人有这方面的经验?

这是我到目前为止所做的:

    private void handleNewClientMessage(SelectionKey key) throws IOException {
    SocketChannel sendingChannel = (SocketChannel) key.channel();

    ByteBuffer receivingBuffer = ByteBuffer.allocate(2048);
    int bytesRead = sendingChannel.read(receivingBuffer);
    if (bytesRead > 0) {
        receivingBuffer.flip();

        byte[] array = new byte[receivingBuffer.limit()];
        receivingBuffer.get(array);
        String message = new String(array);

        System.out.println("Server received "  +message);           
    }
    selector.wakeup();
}

但我无法“结束”该消息,并且肯定会有一条完整的消息。

祝你好运, 0

1 个答案:

答案 0 :(得分:3)

除非您一次只读取一个字节,否则您永远无法确定不会读取多条消息。 (我不建议)。

相反,我会尽可能多地阅读ByteBuffer,然后解析它以找到消息的结尾,例如文字的换行符。

当你发现一行的结尾提取它并将其转换为一个字符串并处理它。重复,直到你有一个部分消息(或什么都没有留下)

如果你发现你只有一部分信息,那么当你拥有并尝试阅读()时,你可以压缩()(如果position()> 0)。

这样您就可以一次阅读尽可能多的邮件,但也可以处理不完整的邮件。

注意:您需要保留ByteBuffer以进行连接,以便了解之前已阅读的部分消息。

注意:如果您的消息大于缓冲区大小,则无法使用此功能。我建议使用可回收的直接ByteBuffer,例如1+ MB。使用直接ByteBuffers,只使用ByteBuffer的页面分配给实际内存。

如果您担心性能问题,我会尽可能重新使用您的byte[]。如果您需要更多空间,则只需要重新分配它。

BTW,您可能会发现使用带有Plain IO的BufferedReader更加简单易用,但性能仍然不错。