NIO初认识之buffer

一.首先掌握NIO的三件套

缓冲区( Buffer)、选择器( Selector)、通道( Channel)

1.Buffer缓冲区

缓冲区实际上是一个容器对象,更直接的说,其实就是一个数组,在NIO库中,所有数据都是用媛冲区处理的。在读
取数据时,它是直接读到缓冲区中的在写入数据时,它也是写入到缓冲区中的;任何时候访问NO中的数据,都
是将它放到冲区中。而在面向流I/O系统中,所有数据都是直接写入或者直接将数据读取到 Stream对象中。
在NIO中,所有的缓冲区类型都继承于抽象类 Buffer,最常用的就是 Bytebuffer,对于Java中的基本类型,基本都有
一个具体 Buffer类型与之相对应

package com.tcc.test.io.buffer;

/**
 * Copyright (C) @2021
 *
 * @author: tcc
 * @version: 1.0
 * @date: 2021/11/27
 * @time: 21:53
 * @description:
 */
import org.junit.Test;


import java.nio.ByteBuffer;


/**
 * 一、缓冲区(Buffer):在Java NIO中负责数据的存取。缓冲区就是数组。用于存储不同数据类型的数据。
 * 根据数据类型不同(boolean 除外),提供了相应类型的缓冲区:
 *  ByteBuffer
 *  CharBuffer
 *  ShortBuffer
 *  IntBuffer
 *  LongBuffer
 *  FloatBuffer
 *  DoubleBuffer
 *  上述缓冲区的管理方式几乎一致,通过allocate()获取缓冲区
 *
 *  二、缓冲区存取数据的两个核心方法:
 *  put():存入数据到缓冲区中
 *  get():获取缓冲区中的数据
 *
 *  三、缓冲区中的四个核心属性:
 *  capacity:容量,表示缓冲区中最大存储数据的容量。一旦声明不能改变。
 *  limit:界限,表示缓冲区中可以操作数据的大小。(limit 后数据不能进行读写)
 *  position:位置,表示缓冲区中正在操作数据的位置。
 *
 *  mark:标记,表示记录当前position的位置。可以通过reset()恢复到mark的位置
 *
 *  0<=mark<=position<=limit<=capacity
 *
 *  四、直接缓冲区和非直接缓冲区:
 *  非直接缓冲区:通过allocate()方法分配缓冲区,将缓冲区建立在JVM的内存中
 *  直接缓冲区:通过allocateDirect()方法分配直接缓冲区,将缓冲区建立在物理内存中,可以提高效率。
 *
 * @author ye.jinhui
 * @create 2017-02-18 10:30
 */
public class TestBuffer {


    @Test
    public void test3() {
        //分配直接缓冲区
        ByteBuffer buf = ByteBuffer.allocateDirect(1024);


        System.out.println(buf.isDirect());//用于判断此字节缓冲区是否为直接缓冲区
    }


    @Test
    public void test2() {
        String str = "abcde";
        ByteBuffer buf = ByteBuffer.allocate(1024);//非直接缓冲区:通过allocate()方法分配缓冲区,将缓冲区建立在JVM的内存中


        buf.put(str.getBytes());


        buf.flip();//写完数据,需要开始读的时候,将postion复位到0,并将limit设为当前postion。
        byte[] dst = new byte[buf.limit()];//limit:界限,表示缓冲区中可以操作数据的大小。(limit 后数据不能进行读写)
        buf.get(dst,0,2);
        System.out.println("new String(dst,0,2)==="+new String(dst,0,2));//ab
        System.out.println("buf.position()=="+buf.position());//position:位置,表示缓冲区中正在操作数据的位置。


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


        buf.get(dst,2,2);
        System.out.println("new String(dst,2,2)=="+new String(dst,2,2));
        System.out.println("buf.position()=="+buf.position());


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


        //判断缓冲区中是否还有数据
        if(buf.hasRemaining()) {
            //获取缓冲区中可以操作的数量
            System.out.println("buf.remaining()=="+buf.remaining());
        }
    }


    @Test
    public void test1() {
        String str = "abcde";
        //1.分配一个指定大小的缓冲区
        ByteBuffer buf = ByteBuffer.allocate(10);


        System.out.println("---------------alllocate()----------------");
        System.out.println("buf.position()=="+buf.position());//0
        System.out.println("buf.limit()=="+buf.limit());//10
        System.out.println("buf.capacity()=="+buf.capacity());//10


        //2.利用put()存入数据到缓冲区
        buf.put(str.getBytes());
        System.out.println("---------------put()----------------");
        System.out.println("buf.position()=="+buf.position());//5
        System.out.println("buf.limit()=="+buf.limit());//10
        System.out.println("buf.capacity()=="+buf.capacity());//10


        //3.切换到读取数据的模式
        buf.flip();
        System.out.println("---------------flip()----------------");
        System.out.println("buf.position()=="+buf.position());//0
        System.out.println("buf.limit()=="+buf.limit());//5
        System.out.println("buf.capacity()=="+buf.capacity());//1o


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


        //5.rewind():可重复读
        buf.rewind();
        System.out.println("---------------rewind()----------------");
        System.out.println("buf.position()=="+buf.position());//0
        System.out.println("buf.limit()=="+buf.limit());//5
        System.out.println("buf.capacity()=="+buf.capacity());//10


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


        System.out.println("(char) buf.get()=="+(char) buf.get());//a
    }


}

 

上一篇:linux select poll epoll IO多路复用简单使用


下一篇:2016 Al-Baath University Training Camp Contest-1