java nio总结

来源:互联网 发布:飞机大战子弹算法 编辑:程序博客网 时间:2024/06/05 19:57

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);
}
}
}

原创粉丝点击