🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
NIO(non-block),是对`java.io.*`包的很多类进行改写,以<mark>块</mark>的方式处理数据,可以提供非阻塞的高伸缩性的网络通信。NIO相关API都在`java.nio.*`包下。 <br/> NIO有三大核心部分组成:Channel,Buffer,Selector。 <br/> BIO是基于字符流和字节流进行传输,而NIO则是基于Channel和Buffer传输。 <br/> IO分为文件IO和网络IO。 <br/> NIO是基于事件驱动,适合服务器需要维持大量的连接,但数据交换量不大的场合。 <br/> **1. `java.nio.Buffer`** ![](https://img.kancloud.cn/ec/60/ec609757884bec8a83bce181891c96c1_1385x228.jpg) Buffer是一个抽象父类,常用的子类有ByteBuffer、CharBuffer、IntBuffer、DoubleBuffer等,Java的每一种基本数据类型都有一个对应的Buffer。 <br/> 常用的是ByteBuffer,它的核心方法如下: ```java put // 存储字节数据到缓冲区 get // 从缓冲区获取数据 array // 将缓存区数据转换为数组 allocate // 设置缓冲区的初始容量 wrap // 将现成的byte数组放入缓冲区 flip // 翻转缓冲区 ``` **2. `java.nio.channels.Channel`** ![](https://img.kancloud.cn/e8/e4/e8e4cb92165da77e5ad4d21708b1dc29_1244x216.jpg) Channel是一个接口,常用的实现类如下: ``` FileChannel 文件读写; DatagramChannel UDP数据读写; ServerSocketChannel、SocketChannel TCP数据读写; ``` ``` FileChannel常用方法: read // 从通道中读取数据放入缓冲区中 write // 缓冲区数据写入到通道中 transferFrom // 把目标通道的数据复制到当前通道 transferTo // 把当前通道的数据复制到目标通道中 ServerSocketChannel常用方法: open // 返回一个新的ServerSocketChannel对象 bind // 绑定一个端口号 configureBlocking // 设置阻塞模式 accept // 接受一个连接 register // 注册一个Selector SocketChannel常用方法: open // 获取一个新的SocketChannel对象 configureBlocking // 设置阻塞模式 connect // 连接服务器 finishConnect // 连接不上服务器的处理 write // 往通道写数据 read // 从通道读数据 register // 注册一个Selector ``` **3. `java.nio.channels.Selector`** ![](https://img.kancloud.cn/b1/36/b13620f12dc6047ea7a8dcbfc1254eb9_1143x169.jpg) Selector选择器,能够检测多个注册的通道是否有事件发生。如果有事件发生,获取该事件然后针对该事件进行相应的处理,这样可以只用一个线程去管理多个通道(多个连接),极大地减少了系统开销,简化了初始化成本和多线程之间上下文切换的成本。 <br/> Selector常用方法: ``` open // 获取一个Selector对象 select // 监控到IO操作进行时,将对应的selectionKey加入到内部集合并返回 selectedKeys // 返回此选择器的选择键集 SelectionKey表示选择器与通道的注册关系,它有如下属性: static int OP_ACCEPT // 有新的网络连接可以accept(接收),值为16 static int OP_CONNECT // 连接已经建立,值为8 static int OP_READ // 读操作,值为1 static int OP_WRITE // 写操作,值为4 selector // 获取与之关联的Selector channel // 获取与之关联的Channel attachment // 获取与之关联的共享数据 interestOps // 设置或改变监听事件 ```