Java NIO(New IO) 从 JDK1.4 开始, 是一个可以替代标准 Java IO 和 Java 网络 IO 的IO API,Java NIO 提供了与标准 IO 不同的 IO 工作方式。
一、Java NIO 的特性:
1、Channels and Buffers:通道和缓冲区
标准的 IO 是基于字节流和字符流进行操作的,而 NIO 是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。
2、Non-blocking IO:非阻塞IO
Java NIO 可以让你非阻塞的使用 IO,例如:一个线程可以要求一个通道将数据读入一个缓冲区,在数据从通道读入缓冲区的期间,这个线程可以进行其他操作,直到数据完成从通道读入到缓冲区时,线程再继续处理它。数据从缓冲区写入通道时也是如此。
3、Selectors:选择器
Java NIO 引入了选择器的概念,选择器可以监听通道中的事件(比如:连接打开,数据到达等)。因此,一个线程就可以监听多个通道的数据传输情况。
二、Java NIO 的核心组件
Java NIO 有以下几个核心组件:
- Channels
- Buffers
- Selectors
除此之外 Java NIO 还有很多类和组件,但 Channel、Buffer 和 Selector 构成了 Java NIO 的核心。其他的组件像 Pipe 和 FileLock 只不过是与三个核心组件联合使用的工具类。
1、Channel 和 Buffer
通常,NIO 中的所有 IO 都从 Channel 开始,Channel 有点类似于 Stream。数据可以从 Channel 读到一个 Buffer 中,也可以从一个 Buffer 写入到一个 Channel 中,如下图所示:
Channel 和 Buffer 有很多种类型,下面是 Java NIO 中 Channel 的主要实现类:
- FileChannel
- DatagramChannel
- SocketChannel
- ServerSocketChannel
可以看到,这些 Channel 涵盖了 UDP 和 TCP 的网络 IO 以及文件的 IO。伴随着这些类的还有一些有意思的接口,简单起见这里不做赘述。
下面是 Java NIO 中 Buffer 的主要实现类:
- ByteBuffer
- CharBuffer
- DoubleBuffer
- FloatBuffer
- IntBuffer
- LongBuffer
- ShortBuffer
这些 Buffer 涵盖了可以通过 IO 传输的基本数据类型:byte、short、int、long、float、double 和 characters。
Java NIO 中还有个 MappedByteBuffer,用于内存映射文件。
2、Selectors
一个 Selector 允许一个线程处理多个 Channel (的事件),这对于应用程序中打开了很多个连接(Channel)但连接中数据传输并不频繁的情况会很有帮助。例如一个聊天服务器。这有一个一个线程使用一个 Selector 同时处理3个 Channel 的示意图:
使用 Selector 时需要将 Channel 注册到 Selector 上,然后调用 Selector 的select()方法。这个方法会一直阻塞直到注册的某个 Channel 的某个 event 就绪,一旦这个方法 return,线程就会处理这些事件。这里说的事件有新连接的到来,数据的接收等。