NIO缓存

传统的IO和NIO的区别:

传统的IO是面向流,阻塞式IO,单向的

NIO:基于通道的,通道内的缓冲区,双向的,非阻塞的,有选择器

通道和缓冲区

通道表示要打开的IO设备(文件/套接字)的连接,需要使用NIO系统,需要获取用于连接IO设备的通道以及用于容纳数据的缓冲区,然后操作缓冲区对数据进行处理

总:channel负责传输,Buffer负责存储

缓冲区

负责数据的存取,缓冲区是数组,用于存储不同的数据类型的数据

根据数据类型的不同(Boolean 除外),提供了相应类型的缓冲区:

ByteBuffer,CharBuffer,ShortBuffer,IntBuffer,LongBuffer,FloatBuffer,DoubleBuffer

上述缓冲区的管理方式几乎一致,通过allocate()获取缓冲区

缓存区中的两个核心方法
put() : 存入数据到缓冲区中
get() : 获取缓冲区中的数据

缓冲区汇中的四个核心属性:
capacity : 容量,表示缓冲区中最大存储数据的容量,一旦声明不能改变
limit : 界限,表示缓冲区中可以操作数据的大小,(limit 后数据不能够读写操作)
position : 位置,表示缓冲区中正在操作数据的位置
mark : 标记,表示记录当前position的位置,可以通过reset()恢复到mark的位置
0 <= mark <= position <= limit <= capacity
@Test
public void test1() {
    String str = "abcde";

    //1 分配一个指定大小的缓冲区
    ByteBuffer buf = ByteBuffer.allocate(1024);

    System.out.println("------------allocate()-----------");
    System.out.println(buf.position());
    System.out.println(buf.limit());
    System.out.println(buf.capacity());
    /*
    结果:
    ------------allocate()-----------
    0
    1024
    1024
    */

    //2 利用put() 存入数据到缓冲区中
    buf.put(str.getBytes());

    System.out.println("--------------put()---------------");
    System.out.println(buf.position());
    System.out.println(buf.limit());
    System.out.println(buf.capacity());
    /*
    结果: 写数据的时候,容量没变,limit也没变
    --------------put()---------------
    5
    1024
    1024
     */
    // 3 切换读取数据模式
    buf.flip();

    System.out.println("------------flip()------------");
    System.out.println(buf.position());
    System.out.println(buf.limit());
    System.out.println(buf.capacity());

    /*
    ------------put()------------
    0
    5
    1024
     */

    //4 利用get() 读取缓冲区中的数据
    System.out.println("-------------get()-----------");
    byte[] dst = new byte[buf.limit()];
    buf.get(dst);
    System.out.println(new String(dst,0,dst.length));

    System.out.println("------------get()-------------");
    System.out.println(buf.position());
    System.out.println(buf.limit());
    System.out.println(buf.capacity());
    /*
    ------------get()-------------
    5
    5
    1024
     */

    //5. rewind():可以重复读取数据
    buf.rewind();
    System.out.println("----------------rewind()-------------");
    System.out.println(buf.position());
    System.out.println(buf.limit());
    System.out.println(buf.capacity());

    //6. clear() 清空缓冲区,但是缓冲区的数据仍然存在,但是处于"被遗忘"状态
    buf.clear();
    System.out.println("---------------clear()---------------");
    System.out.println(buf.position());
    System.out.println(buf.limit());
    System.out.println(buf.capacity());

    System.out.println((char) buf.get());

    /*
    ---------------clear()---------------
    0
    1024
    1024
    a
    */
}

mark标记

@Test
public void test2(){
    String str = "abcde";

    ByteBuffer buf = ByteBuffer.allocate(1024);
    buf.put(str.getBytes());
    //切换到读模式
    buf.flip();
    byte[] dst = new byte[buf.limit()];
    buf.get(dst,0,2);
    System.out.println(new String(dst,0,2));
    System.out.println(buf.position());

    //mark():标记
    buf.mark();

    buf.get(dst,2,2);
    System.out.println(buf.position());

    //reset(): 恢复到mark的位置
    buf.reset();
    System.out.println(buf.position());

    //判断缓冲区中是否还有剩余数据
    if (buf.hasRemaining()){
        //获取缓冲区中可以操作的数量
        System.out.println(buf.remaining());
    }
}
/*
ab
2
4
2
3
 */

猜你喜欢

转载自blog.csdn.net/wwwzydcom/article/details/85225569
NIO