Day30——NIO

1. NIO

1.1 BIO概述

BIO
	BIO ==> Basic IO (基本IO), Block IO(阻塞IO)
	Scanner操作,文件读写操作,Socket数据传输操作... 都是BIO
	
	比如TPC群聊,私聊聊天室
		Socket涉及到的IO,也是BIO
		资源浪费:
			1. 多线程,每一个Socket会对应一个线程,如果用户量巨大,会导致线程过
			多,资源处理过多
			2. 采用阻塞状态,一旦进入阻塞,代码无法执行其他操作。
			3. 承载量一般,吞吐量比较小,同时可靠性不佳

1.2 NIO概述

NIO
	NIO ==> New IO(新IO), Non-Block IO(非阻塞IO)
	NIO非阻塞IO,运行当前程序在处理IO事务时,不会影响其他程序的运行,可以在不使用多线程的情况下,满足IO操作要求。
	三大核心部分:
		通道
			Channel
			文件操作,网络数据传递操作使用的通道
		缓冲
			Buffer
			缓冲使用可以提供操作效率,减少不必要的读写次数
		选择器
			Selector

1.3 Buffer Channel完成文件操作

1.3.1 常用API
java.nio.Buffer
Buffer缓冲区
	ByteBuffer 字节缓冲 常用
	ShortBuffer
	IntBuffer
	LongBuffer 
	CharBuffer 字节缓冲 常用
	FloatBuffer
	DoubleBuffer

常用方法:
	public static ByteBuffer allocate(int capacity);
		按照指定的字节数分配对应的缓冲区空间,保存字节数据
	public byte get(); 
		从字节缓冲区对象中读取一个byte类型数组
	public final Buffer flip();
		翻转缓冲区,回到缓冲区的开始位置。
	public static ByteBuffer wrap(byte[] arr);
		存入一个byte类型数组到缓冲区,会得到一个新的ByteBuffer
	public static ByteBuffer put(byte[] b);
		将字节数组存入缓冲去
		

Channel接口,通道接口
	FileChannel 文件操作通道
	DatagramChannel UDP协议数据包操作的Channel
	ServerSocketChannel TCP服务端ServerSocket对应Channel
	SocketChannel TCP客户端Socket对应Channel
首先操作文件,以FileChannel为例
	public long read(ByteBuffer buffer);
		从通道中读取数据到ByteBuffer中
	public long write(ByteBuffer buffer);
		从Buffer中写数据到通道中
	public long transferFrom(ReadableByteChannel src, long position, long count) 
	从指定srcChannel中,指定位置position开始,读取count个元素,到当前通道中
	文件复制操作。
	
	public long	transferTo(long position, long count, WritableByteChannel target) 
	将当前通道中的数据写入到target中,从当前通道的position位置开始,计数count

1.4 网络编程使用NIO

1.4.1 Selector选择器
Selector
	选择器,网络编程使用NIO的大哥!!!
	服务器可以执行一个线程,运行Selector程序,进行监听操作。
	新连接, 已经连接, 读取数据,写入数据

Selector常用方法:
	public static Selector Open();
		得到一个选择器对象
	public int select(long timeout);
		监听所有注册通道,存在IO流操作是,会将对应的信息SelectionKey存入到内部的集
		合中,参数是一个超时时间
	public Set<SelectionKey> selectionKeys();
		返回当前Selector内部集合中保存的所有SelectionKey
1.4.2 SelectionKey
SelectionKey
	表示Selector和网络通道直接的关系
	int OP_ACCEPT; 16 需要连接
	int OP_CONNECT; 8  已经连接
	int OP_READ; 1  读取操作
	int OP_WRITE; 4 写入操作
SelectionKey
	public abstract Selector selector();
		得到与之关联的 Selector 对象
	public abstract SelectableChannel channel();
		得到与之关联的通道
	public final Object attachment();
		得到与之关联的共享数据
	public abstract SelectionKey interestOps(int ops);
		设置或改变监听事件
	public final boolean isAcceptable();
		是否可以 accept
	public final boolean isReadable();
		是否可以读
	public final boolean isWritable();
		是否可以写
1.4.3 ServerSocketChannel
ServerSocketChannel
	服务端Socket程序对应的Channel通道
常用方法:
	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);
		[重点方法]
			注册当前选择器,并且选择监听什么事件
1.4.4 SocketChannel
SocketChannel
	客户端Socket对应的Channel对象

常用方法:
	public static SocketChannel open();
		打卡一个Socket客户端Channel对象
	public final SelectableChannel configureBlocking(boolean block)
		这里可以设置是阻塞状态,还是非阻塞状态
		false,表示非阻塞
	public boolean connect(SocketAddress remote);
		连接服务器
	public boolean finishConnect();
		如果connect连接失败,可以通过finishConnect继续连接
	public int write(ByteBuffer buf);
		写入数据到缓冲流中
	public int read(ByteBuffer buf);	、
		从缓冲流中读取数据
	public final SelectionKey register(Selector sel, int ops, Object attechment);
		注册当前SocketChannel,选择对应的监听操作,并且可以带有Object attachment参数
	public final void close();
		关闭SocketChannel
发布了20 篇原创文章 · 获赞 52 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_41424681/article/details/104846686