Java NIO疑问与总结

ByteBuffer dst = ByteBuffer.allocate(1024);
SocketChannel clientChannel = (SocketChannel) key.channel();
int read = clientChannel.read(dst);
if (-1 == read) {
    clientChannel.close();
}
if (dst.hasRemaining()) {
clientChannel.close();
}
  • 这里 -1==readdst.hasRemaining() 有啥区别? 上述两种判断方式有啥差异?

  • 什么时候 0 == read ?

  • case1: 如果clientChannel刚好1024个字节:

    • 所以第一次read, 结果肯定不是-1, 而是1024, 即实际读取的字节数, 此时会进入下一次循环, clientChannel.read(dst); 变为”case3”
    • 此时dst.hasRemaining() == false
  • case2: 如果clientChannel可读的<1024个字节(例如128个字节):

    • 所以第一次read, 结果也不是-1, 而是1024, 即实际读取的字节数(128), 此时会进入下一次循环, clientChannel.read(dst); 变为”case3”
    • 此时dst.hasRemaining() == true
  • case3: 如果clientChannel可读的0个字节:

    • 所以第一次read, 结果是-1
    • 此时dst.hasRemaining() == true
      所以, 综上case, dst.hasRemaining() 与 -1==read() 基本一致. 但在case2场景下, 会少一次循环.
      不过一般的应用层协议, 会在请求头里标明本次请求的字节数, 典型的例如ZK, 所以不太需要按照上边这种方式.