NIO三大战神
——————战神1 Channel通道
Channel (通道)
常见的Channel
1 FileChannel 数据文件传输通道
2 DatagramChannel DUP网络传输通道
3 SocketChannel TCP网络传输通道
4ServerSocketChannel TCP网络传输通道
——————战神2Buffer 数据缓冲区
Buffer (数据的内存缓冲区)
常见的Buffer有
1 ByteBuffer 抽象类
实现类
MappedByteBuffer
DirectByteBuffer
HeapByteBuffer
2ShortBuffer
3IntBuffer
4LongBuffer
5FloatBuffer
6DoubleBuffer
7CharBuffer
——————战神3Selector 选择器
Selector 选择器
1selector 是干什么的呢?
在我们传统BIO上是针对每一个请求创建一个线程,每一个线程都是阻塞模式的,而且线程的资源终究是有限的, 即使选择使用线程池也是很浪费资源,那么这个时候我们的selector就上场了
代码案例:
public static void main(String[] args) { try{ FileChannel channel = new FileInputStream("data.txt").getChannel(); //准备缓冲区 ByteBuffer buffer=ByteBuffer.allocate(10);//容量 10个字节 //从channel 读取 写入到buffer while (true){ int len = channel.read(buffer); System.out.print("读取到的字节="+len); if(len==-1){ break; } //打印buffer 内容 buffer.flip();//切换读模式 while (buffer.hasRemaining()){ byte b= buffer.get();//读一个字节 System.out.print((char)b); } buffer.clear();//切换为写模式 } }catch (Exception e){ e.printStackTrace(); } } }
ByteBuffer的使用
ByteBuffer 内部有三个结构
1 capacity 容量大小
2 position 当前读或写处理的位置(指针)
3limit 线程处理 写入限制
首次limit 的位置是 缓冲区最大位置
在 读和写 切换的时候 Position位置是会变动的 例如 写模式从0 写入到位置4 后切换读模式 那么position就会重新变成0 而limit 就会变成写模式position的位置 意思是你最多能读取到刚刚写到截止的那个位置
flip()方法//切换读模式
clear()方法//切换至写模式
读模式读取完毕后,在切换写模式,position 又从新回到0了 因为是又一次读取了 可以覆盖上一次的数据了
compact()方法 是对于缓冲区内未读完的数据进行保留,而切换写模式在保留数据的后面继续写,而不是像clear那样全部删除缓冲区
get(i)获取指定下标的数据 position 位置不会变
public static void main(String[] args) { ByteBuffer buffer= ByteBuffer.allocate(10); buffer.put(new byte[]{'a','b','c','d'}); //切换读模式 buffer.flip(); //从头开始读 buffer.get(new byte[4]); System.out.println(buffer); //从头开始读 buffer.rewind(); System.out.println((char) buffer.get());//读取a System.out.println((char) buffer.get());//读取b buffer.mark();//做标记 通常和reset()配合使用 reset是跳回上次标记的位置 System.out.println(buffer); System.out.println((char) buffer.get());//读取c System.out.println((char) buffer.get());//读取d buffer.reset();// reset是跳回上次mark 标记的位置 System.out.println((char) buffer.get());//读取c }