NIO简介及背景

255 阅读3分钟

NIO简介

非阻塞式IO,像netty就是一个NIO框架;NIO可以通过(Channels)来监听各通道的动作,一个线程就可以完成对多个通道的动作监听,这些动作包括连接就绪、写就绪、读就绪等。
举例说明:建立连接这个动作在BIO中会发生阻塞,直到连接建立完成。这个时候,服务器就需要一个线程在等待连接建立完成;而在NIO中,建立连接只是单线程里Selector监听的一个动作,也就是说:如果监听到连接完成就去处理连接,如果监听到可写,就让该线程去写; 仅仅通过一个线程来处理n多个IO通道(Channels),大大提升了程序处理能力;

一、NIO核心组成部分

1.1 Channels & Buffer
channels:通道 是指各种IO通道(包括File、Socket等),也可以理解为双向IO流,channels可以将自己的内容读到Buffer中,也可以从Buffer中读数据到自己程序上;实现ReadableByteChanel接口,就会有Read()方法,实现WritableByteChannel接口就会提供write()方法。只有,实现这两个接口,那么,才是双向的,才可以双向传输数据;

Buffer 是一个容器,属于一个缓存区,负责存储从Channel里读到的数据和存储准备写入到Channel里面的数据;

常见的Channel:
FileChannel: 文件通道
SocketChannel: 一个连接到TCP网络套接字的通道 ServerSocketChannel: 一个可以监听新进来的TCP连接的通道

常见的Buffer: ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer、ShortBuffer

1.2 Selector
Selector是一个选择处理器,NIO是一个非阻塞式IO,关键点就是在于这个Selector;首先,将Channel注册到Selector中,然后,通过死循环来监听注册在Channel中的事件;这些事件包括:连接就绪、写就绪、读就绪等;

二、NIO核心部分相应函数说明

在网络编程训练之前,先把相关函数做一个了解,便于后续编程;
2.1 Buffer的概念
setp1: 分配空间

image.png
step2: 从通道读取数据,写入Buffer

image.png
step3: 将buffer切换到读模式

image.png
setp4: 将buffer切换到写模式 没读完情况 (这个方法会把所有未读的数据拷贝到Buffer的起始位置,然后position指向最后一个未读数据的后一位)

image.png
step5: 将buffer切换到写模式 数据都读完

image.png
step6: 读取buffer中的数据

image.png
2.1.1 buffer重要属性说明
capacity : buffer数组的总长度(容积)
position : 下一个需要操作的数组元素的位置
limit : 缓存区不可操作的下一个元素 limit <= capacity
mark : 用于记录position的前一个位置,默认为-1

备注 : 注意,像基于Buffer的函数,如flip() compact() clear()其实都是修改position limit而已;
2.1.2 Buffer的分类
ByteBuffer 比较特殊,有子类实现比较多,下面介绍两个子类
HeapByteBuffer : 直接通过byte数组实现在堆上的缓冲区;
DirectByteBuffer : 直接在堆外申请一块内存,将文件映射到该内存空间,在大文件读写方面效率非常高。