NIO与BIO的区别
BIO
- 以流的方式进行操作
- 缓冲区自己创建一个数组
- 阻塞式
NIO
- 以通道 Channel 形式进行操作
- 缓冲区提供 Buffer 进行操作
- 非阻塞式
NIO
NIO - 文件 IO
-
缓冲区: 数据必须放到缓冲区中完成读写操作。
- public abstract ByteBuffer put(byte[] b); 存储字节数据到缓冲区
- public abstract byte[] get(); 从缓冲区获取字节数据
- public final Byte[] array(); 把缓冲区数据转换成字节数组
- public static ByteBuffer allocate(int capacity); 设置缓冲区初始容量
- public static ByteBuffer wrap(byte[] array); 把现成数组放到缓冲区使用
- public final Buffer flip(); 翻转缓冲区,重置位置到初始位置
-
Channel: 类似BIO中的stream,不过是双向的,可写数据,可读数据。
- FileChannel --> 操作文件输入输出
- public int read(ByteBuffer dst); 读数据放入缓冲区
- public int write(ByteBuffer src); 把缓冲区数据放入通道
- public long transferFrom(ReadableByteChannel src, long positon, long count); 从目标通道复制数据。
- public long transferTo(long positon, long count, WriteableByteChannel target); 把数据从当前通道复制给目标通道。
- DatagramChannel --> 基于UDP协议输入输出
- ServerSocketChannel --> 基于TCP协议输入输出,用于服务器端
- SocketChannel --> 基于TCP协议输入输出,用于客户端
- FileChannel --> 操作文件输入输出
NIO之文件IO code
NIO - 网络IO
-
Selector 选择器: 检测多个注册的通道上是否有事件发生,如果有就获取事件,针对时间做相应的响应处理。
- public static Selector open(); 获取一个选择器对象
- public int select(long timeOut); 监控注册的 channel,channel 有 io 操作可以进行时,将对应的 SelectionKey 加入到内部集合并返回,从内部集合得到所有的 SelectionKey 。
- public Set selectionKeys(); 从内部集合中得到所有的 SelectionKey。
-
SelectionKey: 代表 Selector 和 ServerSocketChannel 的注册关系,一共有4种。
- int OP_ACCEPT : 有新的网络连接可以,accept 值为 16
- int OP_CONNECT : 连接已经建立,值为 8
- int OP_READ 和 int OP_WRITE : 代表读写操作, 值为 1 和 4
- public abstract Selector selector(); 得到与之关联的 Selector 对象
- public abstract SelectableChannel channel(); 得到与之关联的 channel 对象
- public final Object attachment(); 得到与之关联的 共享数据
- public final boolean isAcceptable(); 是否可以 accept
- public final boolean isReadable(); 是否可以 读
- public final boolean isWriteable(); 是否可以 写
-
ServerSocketChannel: 服务器监听新的客户端 socket 连接
- public static ServerSocketChannel open(); 得到一个 ServerSocketChannel 通道
- public final ServerSocketChannel bind(SocketAddress local); 设置服务器端端口号
- public final SelectableChannel configureBlocking(boolean block); 设置阻塞或非阻塞模式, false 为非阻塞
- public SocketChannel accept(); 接收连接,返回代表这个连接的通道对象
- public final SelectionKey register(Selector sel, int ops); 注册一个选择器并设置监听事件
-
SocketChannel: 网络 IO 通道,具体负责读写
- public static SocketChannel open(); 得到一个 SocketChannel 通道
- public final SelectableChannel configureBlocking(boolean block); 设置阻塞或非阻塞模式, false 为非阻塞
- public boolean connect(SocketAddress remote); 连接服务器
- public boolean finishConnect(); 上面的方法连接失败,就要通过该方法完成连接操作
- public int read(ByteBuffer dst); 往通道读数据
- public int write(ByteBuffer src); 往通道写数据
- public final SelectionKey register(Selector sel, int ops, Object att); 注册一个选择器,设置监听事件,最后一个参数可以设置共享数据
- public final void close(); 关闭通道
NIO之网络IO code
IO对比总结
IO分为几种,同步阻塞BIO 、 同步非阻塞NIO (1.4) 、异步非阻塞AIO (1.7)
- BIO 方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中。
- NIO 方式适用于链接数目多且连接比较短的架构,比如聊天服务器,并发局限于应用中,编程比较复杂。
- AIO(暂时只是知道有这个东西) 方式使用与连接数目多且连接比较长的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂。
- 同步阻塞 去饭馆点餐,没做好之前啥都不能干,必须等着。
- 同步非阻塞 去饭馆点餐,就可以去玩了,玩了一会就要回饭馆问做好了没有
- 异步非阻塞 点外卖,点完随便干什么,一会就自动给你送过来