java NIO

来源:互联网 发布:打印机扫描软件通用 编辑:程序博客网 时间:2024/06/03 16:24
传统的io叫BIO,Blocked Input Output。
NIO,Non-Blocked Input Output。

1.同BIO的比较

1.1 阻塞与非阻塞

BIO的各种流是阻塞的。这意味着,当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。

1.2 单向与双向

BIO的操作通常是单向的,即一个流必须是InputStreamOutputStream的子类,只能单向处理。
NIO的channel,可以双向读写。所以它比stream可以更好地映射底层操作系统的API。特别是在linux OS中,网络编程的底层通道都是全双工的。

2.Channel

java.nio.channels.Channel

channel是一个通道,通过它可以读取和写入数据。

FileChannel 从文件中读写数据。

DatagramChannel 能通过UDP读写网络中的数据。
SocketChannel 能通过TCP读写网络中的数据。

ServerSocketChannel可以监听新进来的TCP连接,像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel。

3.selector

java.nio.channels.Selector

多路复用器。

它会不断轮询注册在其上的channel,如果某个channel有新的事件(如建立新连接、读事件、写事件),这个channel就处于就绪状态,会被selector轮询出来。然后通过selectionKey可以获取就绪的Channel的集合,进行后续的IO操作。

只需一个线程负责selector轮询,就可以接入成千上万的客户端,这比以前是个非常大的进步。

Selector java.nio.channels.Selector.open()
打开一个selector。
SelectionKey java.nio.channels.SelectableChannel.register(Selector sel, int ops) 
向Selector注册此channel。
SelectableChannel java.nio.channels.SelectionKey.channel()
返回这个SelectionKey对应的channel。
boolean java.nio.channels.SelectionKey.isReadable()
对应的channel是否可读。

int java.nio.channels.Selector.select() 

同步函数。当注册在其上的若干个channel有IO就绪动作时,得到返回。

4.SocketChannel

跟TCP通信相关的channel。

4.1 server

java.nio.channels.ServerSocketChannel
就是ServerSocketChannel。
ServerSocketChannel java.nio.channels.ServerSocketChannel.open()
拿到ServerSocketChannel,起到作构造函数的效果。
ServerSocket java.nio.channels.ServerSocketChannel.socket()
获取ServerSocket。
void java.net.ServerSocket.bind(SocketAddress endpoint)
绑定端口。
SocketChannel java.nio.channels.ServerSocketChannel.accept() 
监听socket收到链接请求,返回一个通信socket。

4.2 client

SocketChannel java.nio.channels.SocketChannel.open(SocketAddress remote)
客户端链接远程端口。

4.3 通信部分

int java.nio.channels.SocketChannel.write(ByteBuffer src)
将src的内容写入channel里。
int java.nio.channels.SocketChannel.read(ByteBuffer dst)
将channel的数据写入dst中。

5.ByteBuffer

java.nio.ByteBuffer

nio中很常见的一个类,用于缓冲字节。
ByteBuffer java.nio.ByteBuffer.allocate(int capacity)
拿到ByteBuffer。初始时,limit为capacity,position为0。
ByteBuffer java.nio.ByteBuffer.put(byte[] src)
将src内容放入自身。

byte[] java.nio.ByteBuffer.array()

以byte数组的形式返回自身内容。
Buffer java.nio.Buffer.flip()

常用于读写模式的反转。

5.1 图解flip

图5-1 put。写模式下,往buffer里写一个字节,并把postion移动一位。写模式下,一般limit与capacity相等。

图5-2 flip。写完数据,需要开始读的时候,将postion复位到0,并将limit设为当前postion。

0 0
原创粉丝点击