JAVA NIO
Java的NIO是通过多路复用Selector
,Channel
,Buffer
,来实现
NIO相较于传统I/O(BIO)
-
NIO是
面向缓冲区
的。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动,这就增加了处理过程中的灵活性。这个可以用于数据包的重组、粘包、拆包等操作。传统I/O是
面向流
的,数据只能在一个流中连续读写,数据没有缓冲,所以字节流也无法前后移动 -
传统I/O是阻塞的,NIO属于非阻塞,就是上面说的多路复用。
Selector
通过selector
(选择器)管理所有的I/O
,Connection
,accept
客户端和服务端的读写---I/O事件
当I/O事件注册到selector
,会被分配一个key,当I/O完成再通过key来找到对应的Channel
,通过Channel
做数据的接收发送操作。selector
用于管理监听多个Channel
事件,因此一个线程可以实现对多个数据Channel
管理。
Buffer
在 Java NIO 中负责数据的存取(存储和读取)。缓冲区就是数组。用于存储不同数据类型的数据
缓冲区中的四个核心属性:
capacity
: 容量,表示缓冲区中最大存储数据的容量。一旦声明不能改变。
limit
: 界限,表示缓冲区中可以操作数据的大小。(limit
后数据不能进行读写)在写模式下,缓冲区的limit表示你最多能往Buffer里写多少数据; 写模式下,limit等于Buffer的capacity.。 读模式,limit意味着你还能从缓冲区获取多少数据。
position
: 位置,表示缓冲区中正在操作数据的位置。当写数据到缓冲时,position表示当前待写入的位置,position最大可为capacity – 1;当从缓冲读取数据时,position表示从当前位置读取。
mark
: 标记,表示记录当前 position
的位置。可以通过 reset()
恢复到 mark
的位置
0 <= mark <= position <= limit <= capacity
Channel
NIO的通道类似于流,但有些区别如下:
-
通道可以同时进行读写,而流只能读或者只能写
-
通道可以实现异步读写数据
-
通道可以从缓冲读数据,也可以写数据到缓冲: 可以从通道读取数据到缓冲区,也可以把缓冲区的数据写到通道中