JDK4 中新加入的 NIO(New Input/Output) 类,引入了一种基于通道(Channel) 与缓存区(Buffer) 的 I/O 方式,它可以直接使用 Native 函数库直接分配堆外内存
1. NIO 与IO 的区别
- IO面向流, NIO面向缓冲区
- IO阻塞, NIO非阻塞
- NIO有选择器
2. NIO 核心组件
- Channels
- Buffers
- Selectors
3. Buffer 缓冲区
- Java NIO Buffers用于和NIO Channel交互。 我们从Channel中读取数据到buffers里,从Buffer把数据写入到Channels;
- Buffer本质上就是一块内存区;
- 一个Buffer有三个属性是必须掌握的,分别是:capacity容量、position位置、limit限制。
3.1 写数据到Buffer有两种方法:
ByteBuffer buf = ByteBuffer.allocate(28);//以ByteBuffer为例子
1.从Channel中写数据到Buffer
int bytesRead = inChannel.read(buf); //read into buffer.
2.通过put写数据:
buf.put(127);
4. Channel(通道)
- Channel(通道)介绍
-
- 通常来说NIO中的所有IO都是从 Channel(通道) 开始的。
- NIO Channel通道和流的区别:
- FileChannel的使用
- SocketChannel和ServerSocketChannel的使用
- ️DatagramChannel的使用
- Scatter / Gather
-
- Scatter: 从一个Channel读取的信息分散到N个缓冲区中(Buufer).
- Gather: 将N个Buffer里面内容按照顺序发送到一个Channel.
- 通道之间的数据传输
-
- 在Java NIO中如果一个channel是FileChannel类型的,那么他可以直接把数据传输到另一个channel。
- transferFrom() :transferFrom方法把数据从通道源传输到FileChannel
- transferTo() :transferTo方法把FileChannel数据传输到另一个channel
5. Selector(选择器)
- Selector(选择器)介绍
-
- Selector 一般称 为选择器 ,当然你也可以翻译为 多路复用器 。它是Java NIO核心组件中的一个,用于检查一个或多个NIO Channel(通道)的状态是否处于可读、可写。如此可以实现单线程管理多个channels,也就是可以管理多个网络链接。
- 使用Selector的好处在于: 使用更少的线程来就可以来处理通道了, 相比使用多个线程,避免了线程上下文切换带来的开销。
- Selector(选择器)的使用方法介绍
-
- Selector的创建
Selector selector = Selector.open();
-
- 注册Channel到Selector(Channel必须是非阻塞的)
channel.configureBlocking(false); SelectionKey key = channel.register(selector, Selectionkey.OP_READ);
-
- SelectionKey介绍
- 一个SelectionKey键表示了一个特定的通道对象和一个特定的选择器对象之间的注册关系。
- 从Selector中选择channel(Selecting Channels via a Selector)
- 选择器维护注册过的通道的集合,并且这种注册关系都被封装在SelectionKey当中.
- 停止选择的方法
- wakeup()方法 和close()方法。
- SelectionKey介绍