NIO的全称是non-blocking IO,也就是非阻塞IO,也有的人叫他New IO。他的核心内容主要有三部分,Channel(通道),Buffer(缓冲区), Selecto(选择器)。下面我们针对这三部分详细了解一下NIO。
Buffer(缓冲区)
Buffer缓冲是一个指定固定数据量的容器,一个连续数组。除内容之外,缓冲区还具有位置和界限,其中位置是要读写的下一个元素的索引,界限是第一个应该读写的元素的索引。java中每个非布尔基本类型都有一个缓冲区类。
Buffer通过capacity, position, limit, mark这四个变量来保存这个数据的当前位置状态,下面介绍一下这四个属性的意义。
- capacity(容量值):缓冲区数组的总长度
- position(位置):下一个要操作的数据元素的位置
- limit(极限):缓冲区数组中不可操作的下一个元素的位置
- mark(标记):用于记录当前position的位置,默认是-1
基本 Buffer 类定义了这些属性以及清除、反转和重绕方法,用以标记当前位置,以及将当前位置重置为前一个标记处。
-
clear()
使缓冲区准备好信道读取或相对放置操作的一个新的序列:它设置了限制的能力和位置为零。 -
flip()
使缓冲区准备好新的通道写入或相对获取操作序列:它将限制设置为当前位置,然后将位置设置为零。 -
rewind()
使缓冲区准备好重新读取已经包含的数据:它保持限制不变,并将位置设置为零。
举例说明Buffer中各个属性:
public static void main(String[] args) { //创建一个10个字节的缓冲区,有两种方法 byte[] bytes = new byte[10]; ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); //ByteBuffer byteBuffer = ByteBuffer.allocate(10); printBufferInfo(byteBuffer); //为缓冲区赋值 for (int i = 0; i < 5; i++) { byteBuffer.put((byte) i); } System.out.println("初始赋值后的buffer信息为..."); printBufferInfo(byteBuffer); } /** * 打印Buffer中的信息 * @param byteBuffer */ public static void printBufferInfo(ByteBuffer byteBuffer) { System.out.println("limit = " + byteBuffer.limit()); System.out.println("capacity = " + byteBuffer.capacity()); System.out.println("position = " + byteBuffer.position()); }
打印结果如下:
limit = 10 capacity = 10 position = 0 初始赋值后的buffer信息为... limit = 10 capacity = 10 position = 5
Channel(通道)
Channel是一个对象,可以通过它读取和写入数据。Channel和传统IO中的Stream很相似。主要区别为:通道是双向的,通过一个Channel既可以进行读,也可以进行写;而Stream只能进行单向操作,通过一个Stream只能进行读或者写,比如InputStream只能进行读取操作,OutputStream只能进行写操作;但是Channel中的所有数据都通过Buffer对象来处理。我们永远不会将字节直接写入通道中,相反是将数据写入包含一个或者多个字节的缓冲区。同样不会直接从通道中读取字节,而是将数据从通道读入缓冲区,再从缓冲区获取这个字节。
Selecto(选择器)
与Selector有关的一个关键类是SelectionKey,一个SelectionKey表示一个到达的事件,主要有OP_ACCEPT(用于套接字准备接受操作位)、OP_CONNECT(用于套接字连接操作的操作位)、OP_READ(读操作的操作位)、OP_WRITE(写操作的操作位)。通过判断SelectionKey处于什么样的状态,进而做对应的操作。
为了避免篇幅太长,影响阅读体验,同时也是想对NIO一层一层的了解,一下灌入太多也不好,所以打算分几篇来介绍学习。上面说了一些概念的东西,下一篇将会结合代码来探究NIO。
来源:https://www.cnblogs.com/wanghq1994/p/12173062.html