I/O(输入/输出)指的是计算机与外界或者一个程序与计算机其余部分交互的接口,相当于人的耳朵和嘴巴。在java编程中,我们最初接触到的就是以的形式完成I/O,正如它的名字:,所有的I/O操作都只能是单向的一个或者多个字节的移动,而且还是阻塞式的,这就造成了效率的低下和资源的浪费。

为了解决这个问题,在JDK1.4中引入了新方案:Java NIO,它既可以说是New IO,也可以说是No-Blocking IONIO和上面提到的IO有相同的作用和目的,只是它使用不同的方式。原来的 I/O 库(在 java.io.*中) 与 NIO (java.nio.*)最重要的区别是数据打包和传输的方式。标准的IO是基于输出流(OutputStream)和输入流(InputStream)进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。

NIO主要包含了以下三个核心组件:

  • Buffer
  • Channel
  • Selector

其实,除以上三个核心组件外,在java.nio.*下还有其他很多类和组件,但它们只不过是上面三个组件共同使用的工具类。

Channel & Buffer(通道和缓冲区)

Channel和标准I/O的流类似,相同点是它们里面装的都是需要传输的数据,不同点是:

  • 流具有方向性,如InputStream只能用于输入,OutputStream只能用于输出;而Channel没有方向,既可以作为输入,也可以作为输出
  • 流中的数据是以一个或者几个字节为单位进行移动,而Channel中的数据是以块为单位进行移动,这样效率更高
  • 可以直接向流中写入或读取数据,而Channel不能,它需要和Buffer配合使用

Channel有如下的几个重要实现:

  • FileChannel
  • DatagramChannel
  • SocketChannel
  • ServerSocketChannel

顾名思义,这些通道涵盖了UDPTCP 网络以及文件的读写。

Buffer本质上是一块可以写入数据,然后从中读取数据的内存,其内部包含一个特定基本数据类型的数组,类似于缓冲流中的数组,主要用来连接Channel和数据介质,相当于数据读写的中转站。

它主要有以下几个关键的Buffer实现:

  • ByteBuffer
  • CharBuffer
  • DoubleBuffer
  • FloatBuffer
  • IntBuffer
  • LongBuffer
  • ShortBuffer

这些Buffer覆盖了你能通过NIO发送的基本数据类型:bytecharshortintlongfloatdouble

Selector (选择器)

Selector能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件。这样,一个单独的线程可以管理多个channel,从而管理多个网络连接。

Java实现OUT参数 java in out_数据

要使用Selector,得向Selector注册Channel,然后调用它的select()方法。这个方法会一直阻塞到某个注册的通道有事件就绪。一旦这个方法返回,线程就可以处理这些事件。