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

    }

 

 

posted @ 2023-04-07 23:50  郎小乐  阅读(16)  评论(0编辑  收藏  举报