您的位置:首页 > 编程语言 > Java开发

java nio总结

2013-06-06 15:02 190 查看
JDK1.4开始,NIO API作为一个基于缓存区,并能提供非阻塞IO操作的API被引入。NIO引入了4个如果概念:

缓存区:表示数据存放的容器,提供可读写的数据缓存区

字符集:用来对缓存区数据进行编码和解码,在字节和字符之间转换

通道:用来接收或发送数据,提供与文件、套接字等的连接,类似于Java IO中的流

选择器:它与可选择通道一起定义了多路的,无阻塞的IO设施

缓存区Buffer:包括ByteBuffer,CharBuffer等

字符集Charset:包括Charset,CharsetEncoder,CharsetDecoder

通道Channel:包括FileChannel,SocketChannel,ServerSocketChannel,DatagramChannel

选择器Selector:包括Selector和事件对象SelectionKey

1、Buffer

4个基本属性:

容量capacity:表示这个Buffer最多能放多少数据,一步是创建Buffer的时候指定。

限制limit:在Buffer上面进行读写操作都不能越过这个下标,写数据时,limit一般和capacity相等,读数据时,limit代表Buffer中有效数据的长度。

位置position:读写操作的当前下标,使用Buffer的相对位置进行读写操作时,读写会从这个下标进行,操作完成后,Buffer会更新下标的值。

标记mark:一个临时存放的下标位置,调用mark()会将mark设置为当前的position值,调用reset()会将position值设置为mark的值。mark值总是小于等于position值。

这些属性满足如下条件:

0 <= mark <= position <= limit <= capacity

3个数据操作:

清除clear():把position设置为0,把limit设置为capacity,一般在把数据写入Buffer前调用

反转flip():把limit设置为当前position,把position设置为0,一般在从Buffer读出数据前调用

重绕rewind():把position设置为0,limit不变,一般在把数据重写入Buffer前调用

2、charset

字符集用来实现字符和字节之间的转换

从CharBuffer到ByteBuffer的编码转换

Charset c = Charset.forName("UTF-8");

CharsetEncoder encoder = c.newEncoder();

ByteBuffer bytebuf = encoder.encode(charBuffer);

从ByteBuffer到CharBuffer的解码转换

Charset c = Charset.forName("UTF-8");

CharsetDecoder decoder = c.newDecoder();

CharBuffer charbuf = decoder.encode(byteBuffer);

3、Channel

Channel通道是用来读写Buffer的IO操作通道,它连接的是底层的物理设备,可以直接支持对设备的读写,或者提供文件锁。

Socket相关的3个Channel,分别是DatagramChannel,SocketChannel,ServerSocketChannel

4、Selector

Selector是非阻塞IO的核心,同时监控多个Channel(Channel必须是非阻塞)的IO状况,对每一个监听到的事件都产生一个SelectionKey对象。

Selector的标准处理模板:

while(true) {

selector.selector()

Iterator<SelectionKey> it = selector.selectedKeys().iteratro();

while(it.hasNext()) {

SelectionKey key = it.next();

it.remove;

if(key.isConnectable()) {

SocketChannel channel = (SocketChannel)key.channel();

channel.register(selector,SelectionKey.OP_READ);

} else if(key.isReadable()) {

SocketChannel channel = (SocketChannel)key.channel();

channel.register(selector,SelectionKey.OP_WRITE);

} else if(key.isWritable()) {

SocketChannel channel = (SocketChannel)key.channel();

channel.register(selector,SelectionKey.OP_READ);

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: