ByteBuffer常用方法与分析

目录

目标

常用API

工具方法

演示案例

allocate(int capacity)和allocateDirect(int capacity)

put()和get()

flip()和hasRemaining()

clear()

compact()

 wrap()

总结


目标

掌握ByteBuffer常用方法,分析ByteBuffer对象在切换读写模式的情况下基本属性的变化情况。

常用API

方法描述案例
allocate(int capacity)分配capacity个字节的缓冲区。返回HeapByteBuffer对象,即jdk内存堆字节缓冲区。ByteBuffer buffer = ByteBuffer.allocate(8);
allocateDirect(int capacity)分配capacity个字节的缓冲区。返回DirectByteBuffer对象,即直接内存字节缓冲区。ByteBuffer buffer = ByteBuffer.allocateDirect(8);
compact()将ByteBuffer切换到写入模式,从position处将缓冲区的字节移动到起始位置。buffer.compact();
get()从ByteBuffer中读取1个字节,并将position向后移动1位。buffer.get();
get(int index)根据index获取指定位置的字节,不会移动position。buffer.get(1);
put(byte[] src)向ByteBuffer写字节数组数据。buffer.put(new byte[]{'1','a'});
buffer.put("1a".getBytes());
put(byte b)向ByteBuffer写字节数据。buffer.put((byte)127);
wrap(byte[] array)向ByteBuffer写字节数组数据。对缓冲区的修改将导致数组被修改,反之亦然。
新缓冲区的大小和limit为字节数组的长度。
ByteBuffer.wrap("Hello World.".getBytes());
flip()将ByteBuffer切换到读模式,position设置为0,limit设置为ByteBuffer内最后1个字节所在的索引数。buffer.flip();
clear()将position设置为0,limit设置为capacity,mark被丢弃。buffer.clear();
capacity()获取ByteBuffer的容量大小。buffer.capacity();
hasRemaining()position和limit之间是否有任何元素。buffer.hasRemaining();

工具方法

    public void bufferDetails(ByteBuffer buffer) {
        System.out.print("position="+buffer.position());
        System.out.print(";limit="+buffer.limit());
        System.out.println(";capacity="+buffer.capacity());
        //读取数据不移动索引。
        for (int i = 0; i < buffer.limit(); i++) {
            System.out.print(buffer.get(i));
            System.out.print(" ");
        }
        System.out.println("\n");
    }

演示案例

allocate(int capacity)和allocateDirect(int capacity)

    /**
     * JVM堆内存字节缓冲区
     * 直接内存字节缓冲区
     */
    public void allocateTest(){
        ByteBuffer buffer = ByteBuffer.allocate(8);
        //是否是直接直接内存字节缓冲区
        System.out.println(buffer.isDirect());

        ByteBuffer buffer2 = ByteBuffer.allocateDirect(8);
        //是否是直接直接内存字节缓冲区
        System.out.println(buffer2.isDirect());

    }

put()和get()

    /**
     * 从ByteBuffer中读取1个字节,并将position向后移动1位。
     */
    public void getAndPutTest(){
        ByteBuffer buffer = ByteBuffer.allocateDirect(20);
        //注意:这里写入的字节数据size不可以超过ByteBuffer的容量,否则报错。
        buffer.put("Hello World !".getBytes());
        //切换到读模式
        buffer.flip();
        //position=0
        System.out.println(buffer.position());
        //输出72,ASCII表中H就是72
        System.out.println(buffer.get());
        //position=1
        System.out.println(buffer.position());
        //继续读取字节缓冲区返回position=1位置的数据,即返回e。
        System.out.println((char)buffer.get());
    }

flip()和hasRemaining()

    /**
     * flip():将ByteBuffer切换到读模式,position设置为0,limit设置为ByteBuffer内最后1个字节所在的索引数。
     * hasRemaining()	position和limit之间是否有任何元素。
     */
    public void flipTest() {
        ByteBuffer buffer = ByteBuffer.allocateDirect(16);
        //注意:这里写入的字节数据size不可以超过ByteBuffer的容量,否则报错。
        buffer.put("123456789".getBytes());
        bufferDetails(buffer);
        //切换到读模式
        buffer.flip();
        bufferDetails(buffer);
        //读取数据并移动position。
        while(buffer.hasRemaining()){
            System.out.println(buffer.get());
        }
        //position=9。
        bufferDetails(buffer);
    }

打印结果

clear()

    /**
     * clear():将position设置为0,limit设置为capacity,mark被丢弃。
     */
    public void clearTest() {
        ByteBuffer buffer = ByteBuffer.allocateDirect(16);
        //注意:这里写入的字节数据size不可以超过ByteBuffer的容量,否则报错。
        buffer.put("123456789".getBytes());
        //切换到读模式
        buffer.flip();
        //读取数据并移动position。
        while(buffer.hasRemaining()){
            buffer.get();
        }
        //position=9。
        bufferDetails(buffer);
        //position=0;limit=16;capacity=16
        buffer.clear();
        bufferDetails(buffer);
    }

打印结果 

compact()

    /**
     * compact():将ByteBuffer切换到写入模式,从position处将缓冲区的字节移动到起始位置。
     */
    public void compactTest(){
        ByteBuffer buffer = ByteBuffer.allocateDirect(16);
        //注意:这里写入的字节数据size不可以超过ByteBuffer的容量,否则报错。
        buffer.put("123456789".getBytes());
        //切换到读模式
        buffer.flip();
        //读取1个字节。此时的buffer为:position=1;limit=9;capacity=16
        buffer.get();
        buffer.compact();
        bufferDetails(buffer);
        //切换到读模式
        buffer.flip();
        //position=0;limit=8;capacity=16,由此打印证明最后一个9不会被重复读取。
        bufferDetails(buffer);
    }

打印结果

 

 wrap()

    /**
     * 向ByteBuffer写字节数组数据。对缓冲区的修改将导致数组被修改,反之亦然。
     * 新缓冲区的大小和limit为字节数组的长度。
     */
    public void wrapTest(){
        byte[] bytes = "123456789".getBytes();
        ByteBuffer buffer =  ByteBuffer.wrap(bytes);
        bufferDetails(buffer);
        buffer.get();
        buffer.compact();
        bufferDetails(buffer);
        //打印234567899,证明了我们对ByteBuffer操作影响了byte[]数组。
        System.out.println(new String(bytes));
        bytes[2]='a';
        //打印了50 51 97 53 54 55 56 57 57,证明了我们对byte[]数组操作影响了ByteBuffer。
        bufferDetails(buffer);
    }

打印结果

总结

区分读模式和写模式的标准在于limit属性,如果ByteBuffer存在剩余空间,则:

  • limit=capacity表示当前为写模式
  • limit=数据量表示当前模式为读模式
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值