NIO

来源:互联网 发布:java遍历jsonobject 编辑:程序博客网 时间:2024/05/21 10:05

传统IO都是阻塞式的输入输出,就是说如果输入输出的数据源中没有数据,程序就会在此阻塞程序的执行,通过字节的移动来处理,系统一次只能出来了一个字节,效率不高。

新IO采用内存映射文件的方式来输入输出,将文件或者一段区域映射到内存,这样就可以像访问内存一样放完文件了,这种方式要比传统IO快得多。


如果说传统的输入输出是系统面向流的处理,则新IO是面向块的处理。


Channel(通道)和Buffer(缓冲)是新IO中的两个核心对象。

Channel是对传统输入输出系统的模拟,在新IO系统中所有的数据都需要通过通道传输。与传统的ImputStream、OutputStream最大的区别在于提供了一个map()方法,通过map()方法直接将一块数据映射到内存中。

Buffer可以被理解成一个容器,本质也是一个数组,发送到Channel中的所有对象都必须首先放到Buffer中,而从Channel中读取的数据也必须先放到Buffer中。


1.Buffer的使用

Buffer是一个抽象类,基本数据类型(除了boolean之外)都有相应的Buffer类,这些Buffer类没有提供构造器,直接调用static XXXBuffer allocate(int capacity)方法,创建一个容量为capacity的XXXBuffer对象。

Buffer中有三个重要的概念:

*容量(capacity):缓冲区的的容量表示该Buffer的最大数据容量,即最多可以存储多少数据,缓冲区的容量不可能为负值,创建后不能改变。

*界限(limit):第一个不应该被读出或者写入的缓冲区位置索引,也就是说,位于limit后的数据即不可被读,也不可被写。

*位置(position):用于指明下一个可以被读出的或者写入的缓冲区位置索引(类似于IO流中的记录指针),当新建一个Buffer对象时,position为0。

初次之外,Buffer还支持一个可选标记mark,0<=mark<=position<=limit<=capacity。

Buffer的主要作用就是装入数据,然后输出数据,开始时position为0,limit为capacity,程序可以通过put()方法像Buffer中放入一些数据(或者从Channel获取一些数据),没放入一些数据,position便向后移动一些位置。当装入数据结束后,调用flip(),该方法将limit设置为position位置,并将position设置为0,这使得Buffer的读写指针又移到了开始的位置,即调用flip()后,Buffer已经为输出数据做好准备。当输出数据结束后,调用clear()方法,该方法不是清空Buffer的数据。它仅仅将position

置为0,将limit设置为capacity。这样为再次像Buffer中装入数据做好准备。


2.Channel的使用

Channel和普通传统流对象的区别在于:Channel可以直接将指定文件的部分或者全部直接映射成Buffer;程序不能直接访问Channel中的数据,包括读取、写入都不行,

Channel只能和Buffer交互。也就说,如果要从Channel中获取数据,必须先用Buffer从Channel中取出一些数据,然后让程序从Buffer中取出这些数据;如果程序要讲数据写入

Channel中,一样先让程序讲数据放入Buffer中,程序再将Buffer里的数据写入Channel中。

Channel的创建都不应该通过构造器来直接创建,而是通过传统的节点InputStream、OutputStream的getChannel()方法来返回对应的Channel,不同的节点流获得的Channel不一样。

Channel中最常用的3类方法时map()、read()、write(),其中map()方法用于将Channel对应的部分或者全部数据映射成ByteBuffer;而read()或者write()方法都有了一系列重载方法,用于从Buffer中读取数据或者向Buffer中写入数据。