我们知道,netty直接与jdk的原生nio开发的,可以说是jdk nio的增强,所以理解jdk nio的机制就变得非常重要,接下来将介绍jdk中关于nio的几个非常重要的组件, 示例源码: github.com/jsbintask22…
对比jdk bio的写法,在从Socket读取数据的时候,不管是客户端还是服务端,我们通常需要将字节读取到一个字节数组,知道读取的数据长度满足所需要的条件:
InputStream is = socket.getInputStream(); byte[] buff = new byte[1024]; int len; while ((len = is.read(buff)) != -1) { System.out.println("client msg: " + new String(buff, 0, len)); } 复制代码
这里的 buff 我们就可以认为是一个数据容器,后续的其他处理(比如这里的 new String)都会从这个数据容器中取。
而在nio编程中,这个字节数组改为了一个可重复使用的容器 Buffer(java.nio.Buffer) ,它有多种同类型的基本类型子类,它的结构如下:
假设有一个长度为 n的容器。
这里指的注意的是 position 代表的是下一个可以读或者可以写的位置,所以读写均会移动位置。
以IntBuffer为例,介绍下它的使用,IntBuffer继承自Buffer,内部使用一个整型数组存储数据 final int[] hb;
put(int i);
, put(int index, int i);
从指定位置的存储不会移动 position 指针的位置。 int get();
, int get(int index);
从指定索引位置获取数据不会移动 positon 位置. return position < limit;
IntBuffer intBuffer = IntBuffer.allocate(10); // 1 for (int i = 0; i < intBuffer.capacity(); i++) { intBuffer.put((i + 1)); // 2 } intBuffer.flip(); // 3 while (intBuffer.hasRemaining()) { // 4 int i = intBuffer.get(); // 5 System.out.println(i); } intBuffer.rewind(); while (intBuffer.hasRemaining()) { int i = intBuffer.get(); System.out.println(i); } 复制代码
limit = position; position = 0; remark = -1;
最后介绍下 rewind, flip, clear 三个方法的区别
position = 0; limit = capacity; mark = -1; limit = position; position = 0; remark = -1; position = 0; mark = -1;