Java NIO
NIO流
在 JDK 1.4 中新加入了 NIO( New Input/ Output)类,引入了一种基于通道和缓冲区的 I/O 方式,它可以使用 Native 函数库直接分配堆外内存,然后通过一个存储在 Java 堆的 DirectByteBuffer 对象作为这块内存的引用进行操作,避免了在 Java 堆和 Native 堆中来回复制数据。
NIO是一种非线程阻塞的IO模型。同步是指线程不断轮询IO事件是否就绪,非阻塞是指线程在等待IO时,可以同时做其他任务。同步的核心就是Selector,Selector代表了线程本事轮询IO事件,避免了阻塞同时减少了不必要的线程消耗;非阻塞的核心就是线程和缓冲区,当IO事件就绪时,可以通过写道缓冲区,保证IO的成功,而无需线程阻塞时的等待。
IO和NIO的区别
| IO | NIO |
|---|---|
| 面向流 | 面向缓冲 |
| 阻塞IO | 基于Selector的非阻塞IO |
Buffer 缓冲区
Java.nio.Buffer是特定的基本类型元素的线性有序序列。
缓冲区的类都有四个属性:
- 容量(Capacity)
- 上界(Limit)
- 位置(Position)
- 标记(Mark)
方法:
- flip()确定缓冲区数据的起始点和终止点
- clear()缓冲区初始化,准备再次接收新数据到缓冲区
- hasRemaining()判断postion到limit之间是否还有元素

缓冲区的分类有ByteBuffer(字节缓冲区)、CharBuffer(字符缓冲区)、ShortBuffer(短整型缓冲区)、IntBuffer(整形缓冲区)、LongBuffer(长整型缓冲区)、FloatBuffer(单精度缓冲区)、DoubleBuffer(双精度缓冲区),就是没有布尔缓冲区。
他们都是抽象类所以不能实例化,然后他们都继承Buffer类,所以都有get()和set()方法,也都可以通过各自的静态方法allocation()创建缓冲区。
该方法是将现有的数组包装到缓冲区中来为缓冲区中的内容分配空间。

Channel 通道
java.nio.Channel通过buffer(缓冲区)进行读写操作,read表示读取通道数据到缓冲区,writer表示把缓冲区数据写入到通道。
Channel需要通过节点流作为创建基础,例如FileInputStream和FileOutputStream的getChannel()方法.RandomAccessFile()也能创建文件通道,支持读写模式。通过IO创建通道是单向的,使用RandomAccessFile创建的通道支持双向。
通道可以异步读写,异步读写表示通道执行读写操作时,也能做别的事情, 解决线程阻塞。如果使用文件管道(FileChannel),建议用 RandomAccessFile 来创建管道,因为该类支持读写模式以及有大量处理文件的方法。
读取文件

写入文件

