NIO学习二-ByteBuffer

前面我们已经了解到Buffer中,0<=mark<=postion<=limit<=capacity。其中mark是标记,如果为-1时丢弃。postion是当前位置,limit是限制,也即上界。capacity是容量。同时了解了直接缓冲区与缓冲区的底层实现是不同的,缓冲区是基于数组的,而直接缓冲区是基于内存的。同时可以基于反射,拿到cleaner,进而拿到clean进行清理。同时clear是还原缓冲区的状态,flip是反转缓冲区的,rewind重绕缓冲区,标记清除。remianing对剩余元素的个数记录。offset获取偏移量。

ByteBuffer是Buffer的子类,可以在缓冲区以字节为单位对数据进行存取。其中put()方法和get方法、视图缓冲区,比如asCharBuffer、压缩compacting、复制duplicating和截取slicing。其中put和get是使用得比较多的,因此方法也比较多。

1.直接缓冲区释放内存:通过反射拿到cleaner、clean,进而清理,或者采用unsafe魔法类进行获取

/**
 * 直接缓冲区释放内存
 */
public class ByteBufferTest1 {
    public static void main(String[] args) throws NoSuchMethodException, InterruptedException, InvocationTargetException, IllegalAccessException {
        System.out.println("使用直接缓冲区");
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(Integer.MAX_VALUE);
        System.out.println("放入信息");
        byte[] byteArray = new byte[]{1};
        System.out.println(Integer.MAX_VALUE);
        for(int i = 0;i<Integer.MAX_VALUE;i++){
            byteBuffer.put(byteArray);
        }
        System.out.println("放入结束");
        Thread.sleep(1000);
        //通过反射获取cleaner、clean进行释放
        Method cleanerMethod = byteBuffer.getClass().getMethod("cleaner");
        cleanerMethod.setAccessible(true);
        Object returnValue = cleanerMethod.invoke(byteBuffer);
        Method cleanMethod = returnValue.getClass().getMethod("clean");
        cleanerMethod.setAccessible(true);
        cleanerMethod.invoke(returnValue);
    }
}

2.使用wrap:

/**
 * 包装wrap数据的处理:将byte数组包装到缓冲区中
 * wrap(byte[] array,int offset,int length)
 * array:缓冲区中的关联的字节数组
 * offset:偏移量
 * length:长度,limit = offset+length
 */
public class ByteBufferTest2 {
    public static void main(String[] args) {
        byte[] byteArray = new byte[]{1, 2, 3, 4, 5, 6, 7, 8};
        ByteBuffer byteBuffer = ByteBuffer.wrap(byteArray);
        ByteBuffer byteBuffer1 = ByteBuffer.wrap(byteArray, 2, 4);
        System.out.println("bytebuffer capacity=" + byteBuffer.capacity() + " " + "limit=" + byteBuffer.limit() + " " + "postion=" + byteBuffer.position());
        System.out.println("bytebuffer1 capacity=" + byteBuffer1.capacity() + " " + "limit=" + byteBuffer1.limit() + " " + "postion=" + byteBuffer1.position());

    }
}

运行结果:

bytebuffer capacity=8 limit=8 postion=0
bytebuffer1 capacity=8 limit=6 postion=2

3.使用get()和put方法:

/**
 * 测试put和get方法,这里put是放元素,get是获取元素
 * put(byte b) get()
 * 一次放入多个元素,进行批量操作
 * put(byte[] src,int offset,int length)
 * =>for(int i=offset;i<offset+length;i++){
 * dst.put(a[i]);
 * }
 * <p>
 * get(byte[] src, int offset,int length)
 * =>for(int i =offset;i<offset+length;i++){
 * dst[i] = src.get(i);
 * }
 * <p>
 * 在使用put(byte[] src,int offset,int length)方法时,需要注意:
 * 1)当offset+length>src.length,抛出IndexOutOfBoundsException异常
 * 2)当参数length的值大于buffer.remaining时,抛出BufferOverflowException异常
 * <p>
 * 在使用get(byte[] dst,int offset,int length)方法时,需要注意:
 * 1)当offset+length>dst.length,抛出IndexOutOfBoundsException异常
 * 2)当参数length的值大于buffer.remaining时,抛出BufferUnderflowException异常
 */
public class ByteBufferTest3 {
    public static void main(String[] args) {
        //仔细观察postion的变化,进行rewind后postion的变化,如果postion后面的位置的数据没有,则默认为0
        // singleElementPutAndGet();
        System.out.println();
        //一次性放入多个数据,进行批量操作
        batchElementPutAndGet();
        System.out.println();
        //测试异常处理,针对写多写少情况进行处理
        exPutByteBufferSolve();
        System.out.println();
        //测试get异常处理,针对写多写少进行处理
        exGetByteBufferSolve();
    }

    private static void singleElementPutAndGet() {
        ByteBuffer buffer = ByteBuffer.allocate(10);
        System.out.println("buffer capacity=" + buffer.capacity() + " limit=" + buffer.limit() + " postion=" + buffer.position());
        buffer.put((byte) 125);
        System.out.println("buffer capacity=" + buffer.capacity() + " limit=" + buffer.limit() + " postion=" + buffer.position());
        buffer.put((byte) 126);
        buffer.rewind();
        System.out.println("buffer capacity=" + buffer.capacity() + " limit=" + buffer.limit() + " postion=" + buffer.position());
        System.out.println(buffer.get());
        System.out.println("buffer capacity=" + buffer.capacity() + " limit=" + buffer.limit() + " postion=" + buffer.position());
        System.out.println(buffer.get());
        System.out.println("buffer capacity=" + buffer.capacity() + " limit=" + buffer.limit() + " postion=" + buffer.position());
        System.out.println(buffer.get());
        byte[] getByteArray = buffer.array();
        for (int i = 0; i < getByteArray.length; i++) {
            System.out.print(getByteArray[i] + " ");
        }
    }


    private static void batchElementPutAndGet() {
        byte[] byteArrayIn1 = {1, 2, 3, 4, 5, 6, 7, 8};
        byte[] byteArrayIn2 = {11, 22, 33, 44};
        //分配空间10
        ByteBuffer byteBuffer = ByteBuffer.allocate(10);
        //将byteArrayIn1放入前面8个位置
        byteBuffer.put(byteArrayIn1);
        //设置当前位置为2
        byteBuffer.position(2);
        //偏移量为1,同时长度为3,长度为<offset+length=4,也即3个元素,从角标1开始,也即第2-4个元素是会放入进去
        //由于当前位置是2,因此下一个位置是3,因此是下面的摆放方式
        //1 2 22 33 44 6 7 8
        byteBuffer.put(byteArrayIn2, 1, 3);
        System.out.print("A=");
        byte[] getByte = byteBuffer.array();
        for (int i = 0; i < getByte.length; i++) {
            System.out.print(getByte[i] + " ");
        }
        System.out.println();
        //设置当前位置为1
        byteBuffer.position(1);
        byte[] byteArrayOut = new byte[byteBuffer.capacity()];
        //设置当前位置为1,偏移量为3,长度为4,因此长度<offset+length=3+4,从角标为3的元素开始,第3-第7个元素会被填充,从而获取
        //由于当前位置为1,因此下一个位置是2,因此拿到的数据是2,也即有4个元素,那么应该是2,22,33,44,所以拿到的数据是
        //0 0 0 2 22 33 44 0 0 0
        byteBuffer.get(byteArrayOut, 3, 4);
        for (int i = 0; i < byteArrayOut.length; i++) {
            System.out.print(byteArrayOut[i] + " ");
        }
    }

    private static void exPutByteBufferSolve() {
        byte[] byteArrayIn1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 23, 24};
        ByteBuffer byteBuffer = ByteBuffer.allocate(10);
        int getArrayIndex = 0;
        while (getArrayIndex < byteArrayIn1.length) {
            int readLength = Math.min(byteBuffer.remaining(), byteArrayIn1.length - getArrayIndex);
            byteBuffer.put(byteArrayIn1, getArrayIndex, readLength);
            byteBuffer.flip();
            byte[] getArray = byteBuffer.array();
            for (int i = 0; i < byteBuffer.limit(); i++) {
                System.out.print(getArray[i] + " ");
            }
            getArrayIndex = getArrayIndex + readLength;
            System.out.println();
            byteBuffer.clear();
        }
    }

    private static void exGetByteBufferSolve() {
        byte[] byteArrayIn = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 22, 33};
        ByteBuffer byteBuffer = ByteBuffer.wrap(byteArrayIn);
        byte[] byteArrayOut = new byte[5];
        while (byteBuffer.hasRemaining()) {
            int readLength = Math.min(byteBuffer.remaining(), byteArrayOut.length);
            byteBuffer.get(byteArrayOut, 0, readLength);
            for (int i = 0; i <readLength; i++) {
                System.out.print(byteArrayOut[i] + " ");
            }
            System.out.println();
        }
    }
}

运行结果:

A=1 2 22 33 44 6 7 8 0 0 
0 0 0 2 22 33 44 0 0 0 
1 2 3 4 5 6 7 8 9 11 
23 24 

1 2 3 4 5 
6 7 8 9 10 
11 22 33 
/**
 * put操作:put(byte[] src),相对批量put()方法,此方法是将给定的源byte数组的所有内容存储到此缓冲区的当前位置中
 * get操作:get(byte[] src),相对批量get()方法,此方法是将此缓冲区remaining的字节传输到给定的目标数组
 *
 * put操作出现异常:
 * 缓冲区的remaining>=数组.length,不会出现异常
 * 缓冲区的remaing<数组.length,会出现异常
 *
 * get操作出现异常:
 * 缓冲区的remaining>=数组.length,不会出现异常
 * 缓冲区的remaining<数组.length,会出现异常
 */
public class ByteBufferTest4 {
    public static void main(String[] args) {
       // putMethod();
        putMethodExceptionSolve();
        System.out.println();
        getMethodExceptionSolve();
    }

    private static void putMethod() {
        byte[] byteArray = new byte[]{3, 4, 5, 6, 78, 8};
        ByteBuffer byteBuffer = ByteBuffer.allocate(10);
        byteBuffer.put((byte) 1);
        byteBuffer.put((byte) 2);
        System.out.println("A=" + byteBuffer.position());
        byteBuffer.put(byteArray);
        System.out.println("B=" + byteBuffer.position());
        byteBuffer.flip();
        byteBuffer.position(3);
        System.out.println("C=" + byteBuffer.position());
        byte[] newArray = new byte[byteBuffer.remaining()];
        byteBuffer.get(newArray);
        //此时会有异常出现,由于此时的remaining<byteArray
        for (int i = 0; i < byteArray.length; i++) {
            System.out.println(newArray[i] + " ");
        }
    }

    private  static void putMethodExceptionSolve(){
        byte[] byteArray = new byte[]{3, 4, 5, 6, 78, 8,9,10};
        ByteBuffer byteBuffer = ByteBuffer.allocate(5);
        //设置两个标识,一个是数组的,一个是remaining的,byteArrayRemaining记录还剩下多少个元素,
        // 而remianing记录byteBuffer还有几个空间可以放,如果剩下的元素比剩下的空间大,则需要进行特殊处理,否者不需要
        int  byteArrayCurrentIndex = 0;
        int byteArrayRemaining = 0;
        while(byteArrayCurrentIndex<byteArray.length){
            byteArrayRemaining = byteArray.length - byteArrayCurrentIndex;
            int readLength = Math.min(byteArrayRemaining,byteBuffer.remaining());
            byte[] newByteArray = Arrays.copyOfRange(byteArray,byteArrayCurrentIndex,byteArrayCurrentIndex+readLength);
            byteBuffer.put(newByteArray);
            byteBuffer.flip();
            byte[] getByte = byteBuffer.array();
            for (int i = 0; i <byteBuffer.limit() ; i++) {
                System.out.print(getByte[i]+" ");
            }
            System.out.println();
            byteArrayCurrentIndex = byteArrayCurrentIndex + readLength;
            byteBuffer.clear();
        }
    }

    private static void getMethodExceptionSolve(){
       byte[] byteArray = new byte[]{1,2,3,4,5,6,7,8,9};
       ByteBuffer byteBuffer = ByteBuffer.wrap(byteArray);
       int copyDataCount =3;
       while (byteBuffer.hasRemaining()){
           byte[] copyByteArray = new byte[Math.min(byteBuffer.remaining(),copyDataCount)];
           byteBuffer.get(copyByteArray);
           for (int i = 0; i < copyByteArray.length; i++) {
               System.out.print(copyByteArray[i]);
           }
           System.out.println();
       }
    }

}

运行结果:

3 4 5 6 78 
8 9 10 

123
456
789

上面介绍了对get()和put()方法的异常处理。

/**
 * put方法操作:put(int index,byte b) 绝对put方法,将给定字节写入此缓冲区的给定索引位置
 * get方法操作:get(int index) 绝对get方法,读取指定位置索引处的字节
 */
public class ByteBufferTest5 {
    public static void main(String[] args) {
        putMethodIndex();
        putMethod();

    }

    private static void putMethodIndex() {
        byte[] byteArrayIn1 = {1, 2, 3, 4, 5, 6, 7, 8};
        ByteBuffer byteBuffer = ByteBuffer.allocate(10);
        byteBuffer.put(byteArrayIn1);
        byteBuffer.put(2, (byte) 127);
        System.out.println(byteBuffer.get(2));
        byteBuffer.position(0);
        byte[] byteArrayOut = new byte[byteBuffer.capacity()];
        byteBuffer.get(byteArrayOut, 0, byteArrayOut.length);
        for (int i = 0; i < byteArrayOut.length; i++) {
            System.out.print(byteArrayOut[i] + " ");
        }
    }

    private static void putMethod() {
        byte[] byteArrayIn1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        ByteBuffer byteBuffer1 = ByteBuffer.wrap(byteArrayIn1);

        byte[] byteArrayIn2 = {55, 66, 77};
        ByteBuffer byteBuffer2 = ByteBuffer.wrap(byteArrayIn2);
        byteBuffer1.position(4);
        byteBuffer2.position(1);

        byteBuffer1.put(byteBuffer2);
        System.out.println("byteBuffer1被改变:" + byteBuffer1.position());
        System.out.println("byteBuffer2被改变:" + byteBuffer2.position());
        byte[] byteArrayOut = byteBuffer1.array();
        for (int i = 0; i < byteArrayOut.length; i++) {
            System.out.print(byteArrayOut[i] + " ");
        }
    }
}

运行结果:

127
1 2 127 4 5 6 7 8 0 0 byteBuffer1被改变:6
byteBuffer2被改变:3
1 2 3 4 66 77 7 8 9 10 

4.slice()方法

/**
 * slice()方法的使用和arrayOffset为非0测试
 * slice()方法的作用:创建新的字节缓冲区,其内容是此缓冲区内容的共享子序列。新缓冲区的内容将从此缓冲区的当前位置开始。
 */
public class ByteBufferTest6 {
    public static void main(String[] args) {
      byte[] byteArrayIn1 = {1,2,3,4,5,6,7,8,9,10};
        ByteBuffer byteBuffer = ByteBuffer.wrap(byteArrayIn1);
        byteBuffer.position(5);
        ByteBuffer byteBuffer1 = byteBuffer.slice();
        System.out.println("byteBuffer.postion="+ byteBuffer.position()+" byteBuffer.capacity="+byteBuffer.capacity()+" byteBuffer.limit="+byteBuffer.limit());
        System.out.println("byteBuffer1.postion="+ byteBuffer1.position()+" byteBuffer1.capacity="+byteBuffer1.capacity()+" byteBuffer1.limit="+byteBuffer1.limit());
        byteBuffer1.put(0,(byte)111);
        byte[] byteArray1 = byteBuffer.array();
        byte[] byteArray2 = byteBuffer1.array();

        for (int i = 0; i < byteArray1.length; i++) {
            System.out.print(byteArray1[i]+" ");
        }
        System.out.println();
        for (int i = 0; i < byteArray2.length ; i++) {
            System.out.println(byteArray2[i]+" ");
        }
    }
}

运行结果:

byteBuffer.postion=5 byteBuffer.capacity=10 byteBuffer.limit=10
byteBuffer1.postion=0 byteBuffer1.capacity=5 byteBuffer1.limit=5
1 2 3 4 5 111 7 8 9 10 
1 2 3 4 5 111 7 8 9 10 

5.解决中文乱码:

/**
 * 进行字符缓冲区转换,其中get()方法采用的编码方式UTF-16BE
 */
public class ByteBufferTest7 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        //会出现乱码现象
       // charBufferDemo();
       // charBufferDemo2();
        charBufferDemo3();
    }

    private  static void charBufferDemo(){
        byte[] byteArrayIn1 = "学无止境".getBytes();
        System.out.println(Charset.defaultCharset().name());
        ByteBuffer byteBuffer = ByteBuffer.wrap(byteArrayIn1);
        System.out.println("byteBuffer="+byteBuffer.getClass().getName());

        CharBuffer buffer =byteBuffer.asCharBuffer();
        System.out.println("charBuffer="+buffer.getClass().getName());
        System.out.println("byteBuffer.postion="+ byteBuffer.position()+" byteBuffer.capacity="+byteBuffer.capacity()+" byteBuffer.limit="+byteBuffer.limit());

        System.out.println(buffer.capacity());
        buffer.position(0);
        for (int i = 0; i < buffer.capacity(); i++) {
            System.out.println(buffer.get()+" ");
        }
    }

    private  static void charBufferDemo2() throws UnsupportedEncodingException {
        byte[] byteArrayIn1 = "学无止境".getBytes("utf-16BE");
        System.out.println(Charset.defaultCharset().name());
        ByteBuffer byteBuffer = ByteBuffer.wrap(byteArrayIn1);
        System.out.println("byteBuffer="+byteBuffer.getClass().getName());

        CharBuffer buffer =byteBuffer.asCharBuffer();
        System.out.println("charBuffer="+buffer.getClass().getName());
        System.out.println("byteBuffer.postion="+ byteBuffer.position()+" byteBuffer.capacity="+byteBuffer.capacity()+" byteBuffer.limit="+byteBuffer.limit());

        System.out.println(buffer.capacity());
        buffer.position(0);
        for (int i = 0; i < buffer.capacity(); i++) {
            System.out.print(buffer.get()+" ");
        }
    }

    private  static void charBufferDemo3() throws UnsupportedEncodingException {
        byte[] byteArrayIn1 = "学无止境".getBytes("utf-8");
        System.out.println(Charset.defaultCharset().name());
        ByteBuffer byteBuffer = ByteBuffer.wrap(byteArrayIn1);
        System.out.println("byteBuffer="+byteBuffer.getClass().getName());

       // CharBuffer buffer =byteBuffer.asCharBuffer();
        CharBuffer buffer = Charset.forName("utf-8").decode(byteBuffer);
        System.out.println("charBuffer="+buffer.getClass().getName());
        System.out.println("byteBuffer.postion="+ byteBuffer.position()+" byteBuffer.capacity="+byteBuffer.capacity()+" byteBuffer.limit="+byteBuffer.limit());

        System.out.println(buffer.capacity());
        buffer.position(0);
        for (int i = 0; i < buffer.limit(); i++) {
            System.out.print(buffer.get()+" ");
        }
    }
}

运行结果:

UTF-8
byteBuffer=java.nio.HeapByteBuffer
charBuffer=java.nio.ByteBufferAsCharBufferB
byteBuffer.postion=0 byteBuffer.capacity=12 byteBuffer.limit=12
6
 ꛦ 鞠  ꋥ ꊃ UTF-8
byteBuffer=java.nio.HeapByteBuffer
charBuffer=java.nio.ByteBufferAsCharBufferB
byteBuffer.postion=0 byteBuffer.capacity=8 byteBuffer.limit=8
4
学 无 止 境 UTF-8
byteBuffer=java.nio.HeapByteBuffer
charBuffer=java.nio.HeapCharBuffer
byteBuffer.postion=12 byteBuffer.capacity=12 byteBuffer.limit=12
12
学 无 止 境 

6.获取字节顺序:

/**
 * 设置与获得字节顺序:order()方法与字节数据排列顺序有关
 * ByteOrder order():获取此缓冲区的字节顺序
 */
public class ByteBufferTest8 {
    public static void main(String[] args) {
        getOrder();
    }

    private static void getOrder(){
        int value = 123456789;
        ByteBuffer byteBuffer = ByteBuffer.allocate(4);
        System.out.print(byteBuffer.order()+" ");
        System.out.print(byteBuffer.order()+" ");
        byteBuffer.putInt(value);
        byte[] byteArray = byteBuffer.array();
        for (int i = 0; i <byteArray.length ; i++) {
            System.out.print(byteArray[i]+" ");
        }

        System.out.println();
        byteBuffer = ByteBuffer.allocate(4);
        System.out.print(byteBuffer.order()+" ");
        byteBuffer.order(ByteOrder.BIG_ENDIAN);
        System.out.print(byteBuffer.order()+" ");
        byteBuffer.putInt(value);
        byteArray = byteBuffer.array();

        for (int i = 0; i < byteArray.length; i++) {
            System.out.print(byteArray[i]+" ");
        }

        System.out.println();

        byteBuffer = ByteBuffer.allocate(4);
        System.out.print(byteBuffer.order()+" ");
        byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
        System.out.print(byteBuffer.order()+" ");
        byteBuffer.putInt(value);
        byteArray = byteBuffer.array();

        for (int i = 0; i < byteArray.length; i++) {
            System.out.print(byteArray[i]+" ");
        }
    }
}

运行结果:

BIG_ENDIAN BIG_ENDIAN 7 91 -51 21 
BIG_ENDIAN BIG_ENDIAN 7 91 -51 21 
BIG_ENDIAN LITTLE_ENDIAN 21 -51 91 7 

7.使用压缩compact:

/**
 * compact()方法的作用:压缩此缓冲区,将缓冲区的当前位置和限制之间的字节复制到缓冲区的开始处
 */
public class ByteBufferTest9 {
    public static void main(String[] args) {
        compactTest();
    }

    private static void compactTest(){
        ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[]{1,2,3,4,5,6});
        System.out.println("A capacity="+ byteBuffer.capacity()+" postion="+byteBuffer.limit());
        System.out.println(" 1 getValue="+ byteBuffer.get());

        System.out.println("B capacity="+byteBuffer.capacity()+" postion="+byteBuffer.limit());
        System.out.println(" 2 getValue="+ byteBuffer.get());

        System.out.println("C capacity="+byteBuffer.capacity()+" postion="+byteBuffer.limit());
        byteBuffer.compact();
        System.out.println("byteBuffer.compact"+byteBuffer.compact());
        System.out.println("D capacity="+byteBuffer.capacity()+" postion="+byteBuffer.limit());
        byte[] getByteArray = byteBuffer.array();
        for (int i = 0; i < getByteArray.length; i++) {
            System.out.print(getByteArray[i]+" ");
        }
    }
}

运行结果:

A capacity=6 postion=6
 1 getValue=1
B capacity=6 postion=6
 2 getValue=2
C capacity=6 postion=6
byteBuffer.compactjava.nio.HeapByteBuffer[pos=2 lim=6 cap=6]
D capacity=6 postion=6
5 6 5 6 5 6 

8.equals和compareTo:

/**
 * 使用equals和CompareTo进行比较
 */
public class ByteBufferTest10 {
    public static void main(String[] args) {
        equalsMethod();
        equalsMethods();
        remainingEquals();
        equalsMethod2();
        compareToMethod();
        compareToMethod2();
    }

    private static void compareToMethod2() {
        byte[] byteBufferIn1 = {3,4,5};
        byte[] byteBufferIn2 = {1,2,3,4,5,6,7,8,9};
        ByteBuffer byteBuffer1 = ByteBuffer.wrap(byteBufferIn1);
        ByteBuffer byteBuffer2 = ByteBuffer.wrap(byteBufferIn2);
        byteBuffer1.position(0);
        byteBuffer2.position(2);
        System.out.println("A="+byteBuffer1.compareTo(byteBuffer2));
    }

    private static void compareToMethod() {
        byte[] byteBufferIn1 = {3,4,5};
        byte[] byteBufferIn2 = {1,2,3,104,5,6,7,8,9};
        ByteBuffer byteBuffer1 = ByteBuffer.wrap(byteBufferIn1);
        ByteBuffer byteBuffer2 = ByteBuffer.wrap(byteBufferIn2);
        byteBuffer1.position(0);
        byteBuffer2.position(2);
        System.out.println("A="+byteBuffer1.compareTo(byteBuffer2));
    }

    private static void equalsMethod2() {
        byte[] byteBufferIn1 = {3,4,5};
        byte[] byteBufferIn2 = {1,2,3,4,5,6,7,8};
        ByteBuffer byteBuffer1 = ByteBuffer.wrap(byteBufferIn1);
        ByteBuffer byteBuffer2 = ByteBuffer.wrap(byteBufferIn2);
        byteBuffer1.position(0);
        byteBuffer1.limit(3);
        byteBuffer2.position(2);
        byteBuffer2.limit(5);
        System.out.println("A="+byteBuffer1.equals(byteBuffer2));
        System.out.println("B byteBuffer1.remaining()="+byteBuffer1.remaining());
        System.out.println("C byteBuffer2.remaining()="+byteBuffer1.remaining());
        byteBuffer2.put(3,(byte)44);
        System.out.println("D="+byteBuffer1.equals(byteBuffer2));
        System.out.println("E byteBuffer1.remaining()="+byteBuffer1.remaining());
        System.out.println("F byteBuffer2.remaining()="+byteBuffer2.remaining());
    }

    private static void remainingEquals() {
        byte[] byteArrayIn1 = {3,4,5};
        byte[] byteArrayIn2 = {1,2,3,4,5,6,7,8};
        ByteBuffer byteBuffer = ByteBuffer.wrap(byteArrayIn1);
        ByteBuffer byteBuffer1 = ByteBuffer.wrap(byteArrayIn2);
        byteBuffer.position(0);
        byteBuffer1.position(3);
        System.out.println("A="+byteBuffer.equals(byteBuffer1));
        System.out.println("byteBuffer.remaining()="+byteBuffer.remaining());
        System.out.println("byteBuffer1.remaining()="+byteBuffer1.remaining());
    }

    private static void equalsMethods() {
        byte[] byteArrayIn1 = {1,2,3,4,5,6,7,8};
        int[] intArrayIn2 = {1,2,3,4,5,6,7,8};
        ByteBuffer byteBuffer = ByteBuffer.wrap(byteArrayIn1);
        IntBuffer intBuffer = IntBuffer.wrap(intArrayIn2);
        System.out.println("isEquals="+byteBuffer.equals(intBuffer));
    }

    private static void equalsMethod() {
        byte[] byteBufferIn1 = {1,2,3,4,5,6};
        ByteBuffer byteBuffer = ByteBuffer.wrap(byteBufferIn1);
        System.out.println("isEquals="+byteBuffer.equals(byteBuffer));
    }


}

运行结果:

isEquals=true
isEquals=false
A=false
byteBuffer.remaining()=3
byteBuffer1.remaining()=5
A=true
B byteBuffer1.remaining()=3
C byteBuffer2.remaining()=3
D=false
E byteBuffer1.remaining()=3
F byteBuffer2.remaining()=3
A=-100
A=-4

9.使用复制duplicate:

/**
 * 复制缓冲区:duplicate()
 */
public class ByteBufferTest11 {
    public static void main(String[] args) {
        duplicateAndSlice();
        duplicateMethod();
    }

    private static void duplicateMethod() {
        byte[] byteBufferIn1 = {1,2,3,4,5};
        ByteBuffer byteBuffer1 = ByteBuffer.wrap(byteBufferIn1);
        ByteBuffer byteBuffer2 = byteBuffer1.duplicate();
        System.out.println("A capacity="+ byteBuffer1.capacity()+" limit="+byteBuffer1.limit()+" postion="+byteBuffer1.position());
        System.out.println("B capacity="+ byteBuffer2.capacity()+" limit="+byteBuffer2.limit()+" postion="+byteBuffer2.position());
        byteBuffer2.put(1,(byte)22);
        byteBuffer2.position(3);
        System.out.println("C capacity="+ byteBuffer1.capacity()+" limit="+byteBuffer1.limit()+" postion="+byteBuffer1.position());
        System.out.println("D capacity="+ byteBuffer2.capacity()+" limit="+byteBuffer2.limit()+" postion="+byteBuffer2.position()+" byteBuffer2的位置是3,而byteBuffer1还是0,说明位置、限制和标记值是独立的 ");

        byteBuffer1.position(0);
        for (int i = byteBuffer1.position(); i < byteBuffer1.limit(); i++) {
            System.out.print(byteBuffer1.get(i)+" ");
        }
    }

    private static void duplicateAndSlice() {
        byte[] byteBufferIn1 = {1,2,3,4,5};
        ByteBuffer byteBuffer1 = ByteBuffer.wrap(byteBufferIn1);
        byteBuffer1.position(2);
        System.out.println("A capacity="+ byteBuffer1.capacity()+" limit="+byteBuffer1.limit()+" postion="+byteBuffer1.position());
        ByteBuffer byteBuffer2 = byteBuffer1.slice();
        ByteBuffer byteBuffer3 = byteBuffer1.duplicate();

        ByteBuffer byteBuffer4 = byteBuffer1;
        System.out.println("B capacity="+ byteBuffer2.capacity()+" limit="+byteBuffer2.limit()+" postion="+byteBuffer2.position());
        System.out.println("C capacity="+ byteBuffer3.capacity()+" limit="+byteBuffer3.limit()+" postion="+byteBuffer3.position());
        byteBuffer2.position(0);
        for (int i = byteBuffer2.position(); i < byteBuffer2.limit(); i++) {
            System.out.print(byteBuffer2.get(i)+" ");
        }
        System.out.println();
        byteBuffer3.position(0);
        for (int i = byteBuffer3.position(); i < byteBuffer3.limit(); i++) {
            System.out.print(byteBuffer3.get(i)+" ");
        }
    }
}

运行结果:

A capacity=5 limit=5 postion=2
B capacity=3 limit=3 postion=0
C capacity=5 limit=5 postion=2
3 4 5 
1 2 3 4 5 A capacity=5 limit=5 postion=0
B capacity=5 limit=5 postion=0
C capacity=5 limit=5 postion=0
D capacity=5 limit=5 postion=3 byteBuffer2的位置是3,而byteBuffer1还是0,说明位置、限制和标记值是独立的 
1 22 3 4 5 

10.对ByteBuffer进行扩容:

/**
 * 对缓冲区进行扩容
 */
public class ByteBufferTest12 {
    public static void main(String[] args) {
        byte[] byteBufferIn1 = {1,2,3,4,5};
        ByteBuffer byteBuffer1 = ByteBuffer.wrap(byteBufferIn1);
        ByteBuffer byteBuffer2 = extendsSize(byteBuffer1,2);

        byte[] newArray = byteBuffer2.array();
        byteBuffer1.position(0);
        for (int i = 0; i < newArray.length; i++) {
            System.out.print(newArray[i]+" ");
        }
    }

    public static ByteBuffer extendsSize(ByteBuffer buffer,int extendsSize){
        ByteBuffer newByteBuffer = ByteBuffer.allocate(buffer.capacity()+extendsSize);
        newByteBuffer.put(buffer);
        return newByteBuffer;
    }
}

运行结果:

1 2 3 4 5 0 0 

从结果中可以看到byteBuffer进行了相对应的扩容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值