NIO目的是用来解决传统IO的问题
NIO中的几个基础概念
一、 通道(Channel):
传统IO进行读写操作:
这里的Stream相当于一个传输的通道。
传统IO中,stream是单向的,如InputStream只能进行读取操作,OutputStream只能进行写操作。
NIO中,channel是双向的,既可以用来进行读取操作,又可以进行写操作。
二、 Buffer(缓冲区)
在NIO中所有数据的读写都离不开Buffer。
三、 Selector(选择器)
作用:用来轮询每个注册的Channel,一旦发现Channel有注册的时间发生,便获取事件然后进行处理。
用单线程处理一个selector,然后通过selector.select()方法来获取到达事件,在获取了到达事件之后,就可以逐个的对这些事件进行响应处理。
Channel
几种常用的通道:
·FileChannel
·SocketChannel
·ServerSocketChannel
·DatagramChannel
通过使用FileChannel可以从文件读或者向文件写入数据;
通过SocketChannel,以TCP来向网络连接的两端读写数据;
通过ServerSocketChannel能够监听客户端发起的TCP连接,并为每个TCP连接创建一个新的SocketChannel来进行数据读写;
通过DatagramChannel,以UDP协议来向网络连接的两端读写数据。
Buffer
缓冲区,实际上是一个容器,是一个连续数组。Channel提供从文件、网络读取数据的渠道,但是读取或写入的数据必须经由Buffer,如下图:
客户端向服务端发送数据时,必须先将数据存入Buffer中,然后将Buffer中的内容写入通道。服务端这边接收数据必须通过Channel将数据读入到Buffer中,然后再从Buffer中取出数据来处理。
在NIO中,Buffer是一个顶级父类,是一个抽象类,常用的Buffer的子类有:
·ByteBuffer
·IntBuffer
·CharBuffer
·LongBuffer
·DoubleBuffer
·DoubleBuffer
·FloatBuffer
·ShortBuffer
如果对于文件读写,上面的几种Buffer都可能会用到。但是对于网络读写来说,用到最多的是ByteBuffer。
Selector
Selector是NIO中的核心类,selector能够检测多个注册的通达上是否有事件发生,如果有事件发生,便获取事件然后针对每个事件进行相应的响应处理。这样一来,只是用一个单线程就可以管理多个通道,也就是管理多个连接。这样使得只有在连接真正有读写事件发生时,才会调用函数来进行读写,就大大减少了系统的开销,并且不必为每个连接都创建一个线程,不用去维护多个线程,并且避免了多线程之间上下文切换导致的开销。