zoukankan      html  css  js  c++  java
  • Java NIO 三大组件之 Buffer

    NIO大三组件 之Buffer

    一、什么是Buffer

    Buffer是用于特定原始类型的数据的容器。 它的实质就是一组数组,用于存储不同类型的数据。

    二、缓冲区的类型

    缓冲区类型除了Boolean值类型外,其余基本类型都含有。

    NIO中定义的抽象缓冲区对象如下(均继承至Buffer抽象类):

    • ByteBuffer
    • CharBuffer
    • ShortBuffer
    • IntBuffer
    • LongBuffer
    • FloatBuffer
    • DoubleBuffer

    上述类均为抽象类,它们的实现还分有直接缓冲区和非直接缓冲区。

    三、缓冲区中的四个核心属性

    • category: 容量,表示缓冲区的大小,一旦声明就不可改变。
    • limit: 界限,表示缓冲区中可以操作数据的大小。(llimit后面的数据不可读写)
    • position: 位置,表示缓冲区中正在操作数据的位置。
    • mark: 标记,可以标记当前position的位置。

    写操作

    进行写操作时,limit=category,limit表示的是可以写的地址范围。

    position则表示当前写的索引,每写一个字节position则+1。

    读操作

    进行读操作时,limit=position,limit此时则表示可读取的范围,此时范围则会被赋值为写的position

    而当position赋值完给limit后,position则置零。在读操作中position则表示读的索引。

    它们之间的关系

    mark <= position <= limit <= capacity

    @Test
    public void markTest(){
        String str = "abcde";
    
    
        ByteBuffer buf = ByteBuffer.allocate(1024);
        byte[] bytes = new byte[10];
        buf.put(str.getBytes());
    
        //切换到读模式
        buf.flip();
        //获取buf的两个字节
        buf.get(bytes, 0, 2);
        System.out.println(new String(bytes));
    
        //标记position的位置
        buf.mark();
        //获取buf的两个字节
        buf.get(bytes, 2, 2);
        System.out.println(new String(bytes));
        System.out.println(buf.position());
        //回到position=2的位置
        buf.reset();
    
        System.out.println(buf.position());
    }
    

    四、存取缓冲区数据的核心方法

    • put():存入数据到缓冲区中
    • get(): 获取缓冲区中的数据
    • flip(): 读写切换
    • clear():清空写缓存,,只是把position和limit重置为最初状态,但是缓存区的内容并没有删除
    • mark(): 保存当前position的位置
    • reset(): 把当前的position重置为mark的值
    • rewind(): 重读操作,position置0
        @Test
        public void bufferMethodTest(){
            String str = "abcde";
    
            //声明一个Byte缓冲区(非直接缓冲区),并设置缓冲区大小为1024
            ByteBuffer buf = ByteBuffer.allocate(1024);
            //直接缓冲区申请方式
            //ByteBuffer.allocateDirect(1024);
            System.out.println("-------------------------allocate------------------------");
            //0
            System.out.println(buf.position());
            //1024
            System.out.println(buf.limit());
            //1024
            System.out.println(buf.capacity());
    
            System.out.println("-------------------------put------------------------");
            //把str的数据放入缓冲区
            buf.put(str.getBytes());
            //5
            System.out.println(buf.position());
            //1024
            System.out.println(buf.limit());
            //1024
            System.out.println(buf.capacity());
    
            //3.切换读取数据模式
            buf.flip();
            System.out.println("-------------------------get------------------------");
            byte[] bytes = new byte[20];
            //读取缓冲区理的5个字节
            buf.get(bytes,0, buf.limit());
            //5,表示数据读到的位置
            System.out.println(buf.position());
            //5.表示可以读的位置
            System.out.println(buf.limit());
            System.out.println(buf.capacity());
    
            //5. rewind: 可重读
            buf.rewind();
            System.out.println("-------------------------rewind------------------------");
            //position回到0
            System.out.println(buf.position());
            //5.表示可以读的位置,5
            System.out.println(buf.limit());
            System.out.println(buf.capacity());
    
            //clear(): 清空缓存区,但数据任然存在,只是把position和limit重置为最初状态。
            buf.clear();
            System.out.println("-------------------------clear------------------------");
            //postion变为0
            System.out.println(buf.position());
            //1024
            System.out.println(buf.limit());
            System.out.println(buf.capacity());
        }
    

    五、补充

    关于直接缓冲区与非直接缓冲区

    • 直接缓冲区: 缓冲区地址直接映射到磁盘地址。
    • 非直接缓冲区: 缓冲区地址先通过JVM缓存,然后再由JVM向OS申请内存空间。(实质是堆)
    两种方式的优缺点
    1. 非直接缓冲区有JVM到OS这段中间开销,使得访问性能下降。但是由于缓存在JVM堆中,数据受程序控制。
    2. 直接缓冲区没有中间开销,但由于内存是向OS申请,缓冲区的数据存储不受程序的控制。
      非直接缓冲区
      直接缓冲区
  • 相关阅读:
    垃圾回收于内存优化(摘自网络)
    as3.0 动态改变影片剪辑的颜色
    2进制_8进制_16进制之间快速转换的技巧.txt
    24位真彩色转换为8位灰度图片(完整代码)
    大端模式和小端模式
    如何将真彩色图转换为各种灰度图
    C++图像缩放
    二进制转十进制快速转换方法
    电脑上运行的使用大全
    移位运算符详解
  • 原文地址:https://www.cnblogs.com/mostro/p/11977276.html
Copyright © 2011-2022 走看看