NIO在jdk1.4引入,是面向块(缓冲区)编程,而IO是面向流编程
面向块(缓冲区)编程:
数据的读写必须经过缓冲区
我们可以使用Buffer所对应的子类将数据从通道(Channel)流向缓冲区
从缓冲区写到通道叫做读取缓冲区
过程图分析
NIO主要有三大核心部分:
Channel(通道)
Buffer(缓冲区)
Selector(选择器)
还有一个charset(编码)了解下
Buffer(缓冲区)
Buffer是一个抽象类,针对缓冲区封装的一个类,提供相应的方法来操作这个缓冲区
子类
ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer
核心类
ByteBuffer
和CharBuffer
ByteBuffer有一个子类 MappedByteBuffer
MappedByteBuffer类能够将文件直接映射到内存中,这样我们就可以像访问内存一样访问文件,非常方便
获取Buffer
获取ByteBuffer
static ByteBuffer allocate(int capacity)
分配一个新的字节缓冲区。
static ByteBuffer allocateDirect(int capacity)
分配新的直接字节缓冲区。
二者获取Buffer的区别
1.创建普通Buffer成本低,读写的效率不高
2.因为创建直接Buffer成本高,所以我们一般用在Buffer生存周期较长的时候使用
3.只有ByteBuffer才能够创建直接Buffer,其他的Buffer对象是不能够创建
4.如果创建了直接Buffer但是我又想要使用其他Buffer的功能,可以将ByteBuffer转换成其他Buffer
例如:asIntBuffer()
四个非常重要的概念
capacity
: 缓冲区的容量,不可以为负数,一旦创建了就不能够改变
limit
:无效缓冲区的第一个位置索引,limit后面的数据既不可读,也不可写
position
:下一个可以被读取或者写入的缓冲区位置索引
mark
:标记索引,该索引能够用于下次读取或者写入,它只能够在0-position之间
四个系数的关系:
0 < mark < postion < limit < capacity
五个方法
1、flip(): 将写模式切换为读模式, 将limit的值改为postion的值,同时将postion归0
特点: 就是为下一次数据的读取做好准备
2、clear(): 将读模式切换为写模式,将limit改为capacity的值,同时将postion归0
特点: 就是为下一次数据的写入做好准备
3、put(): 相对读取,向Buffer中存储数据
4、get(): 相对读取,从Buffer中获取数据
5、mark(): 设置标记位
reset(): 重置
hasRemaining(): 判断当前位置和limit之间是否还有元素可处理
绝对读取和相对读取的关系
绝对读取: get(index) 不会影响position的位置
相对读取: put() get() 会影响,每次读取一次,指针后移
举例代码如下
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.IntBuffer;
public class NIODemo {
public static void main(String[] args) {
// ByteBuffer buffer = ByteBuffer.allocate(5);
ByteBuffer buffer2 = ByteBuffer.allocateDirect(10);
CharBuffer buffer = CharBuffer.allocate(8);
// 准备向Buffer中写数据 写模式
System.out.println("capacity:" + buffer.capacity()); // 8
System.out.println("limit:" + buffer.limit()); // 8
System.out.println("position:" + buffer.position()); // 0
buffer.put('x');
buffer.put('y');
buffer.put('r');
System.out.println("------------------------");
System.out.println("capacity:" + buffer.capacity()); // 8
System.out.println("limit:" + buffer.limit()); // 8
System.out.println("position:" + buffer.position()); // 3
System.out.println("------------------------");
// 切换模式 ,limit变为position的位置然后将position变为0
//将写模式切换成读模式
buffer.flip();
System.out.println("capacity:" + buffer.capacity()); // 8
System.out.println("limit:" + buffer.limit()); // 3
System.out.println("position:" + buffer.position()); // 0
System.out.println("------------------------");
char ch = 0;
ch = buffer.get();
System.out.println(ch);//x
buffer.mark();// mark: 1
ch = buffer.get();
System.out.println(ch);//y
Sy