一、概述
我们在之前的文章中介绍输入输出流的时候提到过,输入流InputStream的read方法从输入流中读取数据的时候,如果数据源中没有数据,那么这个方法会阻塞。输出流OutputStream的write方法在写入数据时同样也会阻塞,也就是之前介绍的输入、输出流都是阻塞式的。不仅如此,传统的输入、输出流都是通过字节的移动来处理的,也就是说面向流的输入输出每次只能处理一个字节,因此面向流的输入输出体系通常效率不高。
Java从1.4版本开始,提供了一系列改进输入输出流的类,这些类都存放在Java.nio包下,新IO和传统IO有相同的目的,都是用于处理输入输出,但是新的IO使用了不同的方式来处理输入输出,通过使用内存的方式来加快数据处理速度,并且提供了更加丰富的API以供使用者操作。
二、概念模型
Buffer使用内存映射的方式来处理输入输出,Buffer将文件或者文件的一部分映射到内存中,这样就可以像访问内存一样访问文件了,通过这种方式访问文件要快很多,所以传统的输入输出是面向流的处理,那么新的输入输出则是面向"块"的处理。
Buffer可以理解成一个容器,发送到channel或者从channel中读取数据都需要先经过buffer进行处理,此处的buffer类似于一个缓冲器,既可以多次访问,每次访问获取一点数据,也可以一次映射某"块"数据加以处理。
从内部结构上来看,buffer就是一个数组,可以保存相同类型的一组数据,它有三个比较重要的概念:容量(capacity)、界限(limit)、位置(position)。
容量:缓冲区的容量表示buffer可以存储的最多数据量,缓冲区的容量不可能为负值,并且创建后不可修改;
界限:可以被读取或者可被写入的最大位置;
位置:用于标志下一个可以被读取或者写入的位置索引;
当初始化一个buffer时,capacity为buffer边界最大值,limit为capacity,position为0,当写入一段数据之后,capacity不变,limit不变,position为写入数据最大值;再次写入数据,capacity不变,limit不变,position为两次数据和的最大值。当要读取数据时,设置buffer状态为读之后,capacity不变,limit为两次写入数据最大位置,position为0;读取一部分数据之后,capacity不变,limit不变,position为读取数据最大值位置。
buffer读写数据模型如下图所示:
三、buffer提供的API
1、java.nio.Buffer API
名称 |
返回值 |
功能 |
Buffer(int mark, int pos, int lim, int cap) |
无 |
构造方法,包私有,用户不能使用,一般由子类调用,并设置相关参数 |
position(int newPosition) |
Buffer |
重新设置position位置,如果Mark大于原position位置,则Mark置-1 |
limit(int newLimit) |
Buffer |