NIO学习二-ByteBuffer

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

前面我们已经了解到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魔法类进行获取

/*** 直接缓冲区释放内存*/publicclassByteBufferTest1 {
publicstaticvoidmain(String[] args) throwsNoSuchMethodException, InterruptedException, InvocationTargetException, IllegalAccessException {
System.out.println("使用直接缓冲区");
ByteBufferbyteBuffer=ByteBuffer.allocateDirect(Integer.MAX_VALUE);
System.out.println("放入信息");
byte[] byteArray=newbyte[]{1};
System.out.println(Integer.MAX_VALUE);
for(inti=0;i<Integer.MAX_VALUE;i++){
byteBuffer.put(byteArray);
        }
System.out.println("放入结束");
Thread.sleep(1000);
//通过反射获取cleaner、clean进行释放MethodcleanerMethod=byteBuffer.getClass().getMethod("cleaner");
cleanerMethod.setAccessible(true);
ObjectreturnValue=cleanerMethod.invoke(byteBuffer);
MethodcleanMethod=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*/publicclassByteBufferTest2 {
publicstaticvoidmain(String[] args) {
byte[] byteArray=newbyte[]{1, 2, 3, 4, 5, 6, 7, 8};
ByteBufferbyteBuffer=ByteBuffer.wrap(byteArray);
ByteBufferbyteBuffer1=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());
    }
}

运行结果:

bytebuffercapacity=8limit=8postion=0bytebuffer1capacity=8limit=6postion=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异常*/publicclassByteBufferTest3 {
publicstaticvoidmain(String[] args) {
//仔细观察postion的变化,进行rewind后postion的变化,如果postion后面的位置的数据没有,则默认为0// singleElementPutAndGet();System.out.println();
//一次性放入多个数据,进行批量操作batchElementPutAndGet();
System.out.println();
//测试异常处理,针对写多写少情况进行处理exPutByteBufferSolve();
System.out.println();
//测试get异常处理,针对写多写少进行处理exGetByteBufferSolve();
    }
privatestaticvoidsingleElementPutAndGet() {
ByteBufferbuffer=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 (inti=0; i<getByteArray.length; i++) {
System.out.print(getByteArray[i] +" ");
        }
    }
privatestaticvoidbatchElementPutAndGet() {
byte[] byteArrayIn1= {1, 2, 3, 4, 5, 6, 7, 8};
byte[] byteArrayIn2= {11, 22, 33, 44};
//分配空间10ByteBufferbyteBuffer=ByteBuffer.allocate(10);
//将byteArrayIn1放入前面8个位置byteBuffer.put(byteArrayIn1);
//设置当前位置为2byteBuffer.position(2);
//偏移量为1,同时长度为3,长度为<offset+length=4,也即3个元素,从角标1开始,也即第2-4个元素是会放入进去//由于当前位置是2,因此下一个位置是3,因此是下面的摆放方式//1 2 22 33 44 6 7 8byteBuffer.put(byteArrayIn2, 1, 3);
System.out.print("A=");
byte[] getByte=byteBuffer.array();
for (inti=0; i<getByte.length; i++) {
System.out.print(getByte[i] +" ");
        }
System.out.println();
//设置当前位置为1byteBuffer.position(1);
byte[] byteArrayOut=newbyte[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 0byteBuffer.get(byteArrayOut, 3, 4);
for (inti=0; i<byteArrayOut.length; i++) {
System.out.print(byteArrayOut[i] +" ");
        }
    }
privatestaticvoidexPutByteBufferSolve() {
byte[] byteArrayIn1= {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 23, 24};
ByteBufferbyteBuffer=ByteBuffer.allocate(10);
intgetArrayIndex=0;
while (getArrayIndex<byteArrayIn1.length) {
intreadLength=Math.min(byteBuffer.remaining(), byteArrayIn1.length-getArrayIndex);
byteBuffer.put(byteArrayIn1, getArrayIndex, readLength);
byteBuffer.flip();
byte[] getArray=byteBuffer.array();
for (inti=0; i<byteBuffer.limit(); i++) {
System.out.print(getArray[i] +" ");
            }
getArrayIndex=getArrayIndex+readLength;
System.out.println();
byteBuffer.clear();
        }
    }
privatestaticvoidexGetByteBufferSolve() {
byte[] byteArrayIn= {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 22, 33};
ByteBufferbyteBuffer=ByteBuffer.wrap(byteArrayIn);
byte[] byteArrayOut=newbyte[5];
while (byteBuffer.hasRemaining()) {
intreadLength=Math.min(byteBuffer.remaining(), byteArrayOut.length);
byteBuffer.get(byteArrayOut, 0, readLength);
for (inti=0; i<readLength; i++) {
System.out.print(byteArrayOut[i] +" ");
            }
System.out.println();
        }
    }
}

运行结果:

A=1222334467800000222334400012345678911232412345678910112233
/*** put操作:put(byte[] src),相对批量put()方法,此方法是将给定的源byte数组的所有内容存储到此缓冲区的当前位置中* get操作:get(byte[] src),相对批量get()方法,此方法是将此缓冲区remaining的字节传输到给定的目标数组** put操作出现异常:* 缓冲区的remaining>=数组.length,不会出现异常* 缓冲区的remaing<数组.length,会出现异常** get操作出现异常:* 缓冲区的remaining>=数组.length,不会出现异常* 缓冲区的remaining<数组.length,会出现异常*/publicclassByteBufferTest4 {
publicstaticvoidmain(String[] args) {
// putMethod();putMethodExceptionSolve();
System.out.println();
getMethodExceptionSolve();
    }
privatestaticvoidputMethod() {
byte[] byteArray=newbyte[]{3, 4, 5, 6, 78, 8};
ByteBufferbyteBuffer=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=newbyte[byteBuffer.remaining()];
byteBuffer.get(newArray);
//此时会有异常出现,由于此时的remaining<byteArrayfor (inti=0; i<byteArray.length; i++) {
System.out.println(newArray[i] +" ");
        }
    }
privatestaticvoidputMethodExceptionSolve(){
byte[] byteArray=newbyte[]{3, 4, 5, 6, 78, 8,9,10};
ByteBufferbyteBuffer=ByteBuffer.allocate(5);
//设置两个标识,一个是数组的,一个是remaining的,byteArrayRemaining记录还剩下多少个元素,// 而remianing记录byteBuffer还有几个空间可以放,如果剩下的元素比剩下的空间大,则需要进行特殊处理,否者不需要intbyteArrayCurrentIndex=0;
intbyteArrayRemaining=0;
while(byteArrayCurrentIndex<byteArray.length){
byteArrayRemaining=byteArray.length-byteArrayCurrentIndex;
intreadLength=Math.min(byteArrayRemaining,byteBuffer.remaining());
byte[] newByteArray=Arrays.copyOfRange(byteArray,byteArrayCurrentIndex,byteArrayCurrentIndex+readLength);
byteBuffer.put(newByteArray);
byteBuffer.flip();
byte[] getByte=byteBuffer.array();
for (inti=0; i<byteBuffer.limit() ; i++) {
System.out.print(getByte[i]+" ");
            }
System.out.println();
byteArrayCurrentIndex=byteArrayCurrentIndex+readLength;
byteBuffer.clear();
        }
    }
privatestaticvoidgetMethodExceptionSolve(){
byte[] byteArray=newbyte[]{1,2,3,4,5,6,7,8,9};
ByteBufferbyteBuffer=ByteBuffer.wrap(byteArray);
intcopyDataCount=3;
while (byteBuffer.hasRemaining()){
byte[] copyByteArray=newbyte[Math.min(byteBuffer.remaining(),copyDataCount)];
byteBuffer.get(copyByteArray);
for (inti=0; i<copyByteArray.length; i++) {
System.out.print(copyByteArray[i]);
           }
System.out.println();
       }
    }
}

运行结果:

3456788910123456789

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

/*** put方法操作:put(int index,byte b) 绝对put方法,将给定字节写入此缓冲区的给定索引位置* get方法操作:get(int index) 绝对get方法,读取指定位置索引处的字节*/publicclassByteBufferTest5 {
publicstaticvoidmain(String[] args) {
putMethodIndex();
putMethod();
    }
privatestaticvoidputMethodIndex() {
byte[] byteArrayIn1= {1, 2, 3, 4, 5, 6, 7, 8};
ByteBufferbyteBuffer=ByteBuffer.allocate(10);
byteBuffer.put(byteArrayIn1);
byteBuffer.put(2, (byte) 127);
System.out.println(byteBuffer.get(2));
byteBuffer.position(0);
byte[] byteArrayOut=newbyte[byteBuffer.capacity()];
byteBuffer.get(byteArrayOut, 0, byteArrayOut.length);
for (inti=0; i<byteArrayOut.length; i++) {
System.out.print(byteArrayOut[i] +" ");
        }
    }
privatestaticvoidputMethod() {
byte[] byteArrayIn1= {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
ByteBufferbyteBuffer1=ByteBuffer.wrap(byteArrayIn1);
byte[] byteArrayIn2= {55, 66, 77};
ByteBufferbyteBuffer2=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 (inti=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()方法的作用:创建新的字节缓冲区,其内容是此缓冲区内容的共享子序列。新缓冲区的内容将从此缓冲区的当前位置开始。*/publicclassByteBufferTest6 {
publicstaticvoidmain(String[] args) {
byte[] byteArrayIn1= {1,2,3,4,5,6,7,8,9,10};
ByteBufferbyteBuffer=ByteBuffer.wrap(byteArrayIn1);
byteBuffer.position(5);
ByteBufferbyteBuffer1=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 (inti=0; i<byteArray1.length; i++) {
System.out.print(byteArray1[i]+" ");
        }
System.out.println();
for (inti=0; i<byteArray2.length ; i++) {
System.out.println(byteArray2[i]+" ");
        }
    }
}

运行结果:

byteBuffer.postion=5byteBuffer.capacity=10byteBuffer.limit=10byteBuffer1.postion=0byteBuffer1.capacity=5byteBuffer1.limit=512345111789101234511178910

5.解决中文乱码:

/*** 进行字符缓冲区转换,其中get()方法采用的编码方式UTF-16BE*/publicclassByteBufferTest7 {
publicstaticvoidmain(String[] args) throwsUnsupportedEncodingException {
//会出现乱码现象// charBufferDemo();// charBufferDemo2();charBufferDemo3();
    }
privatestaticvoidcharBufferDemo(){
byte[] byteArrayIn1="学无止境".getBytes();
System.out.println(Charset.defaultCharset().name());
ByteBufferbyteBuffer=ByteBuffer.wrap(byteArrayIn1);
System.out.println("byteBuffer="+byteBuffer.getClass().getName());
CharBufferbuffer=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 (inti=0; i<buffer.capacity(); i++) {
System.out.println(buffer.get()+" ");
        }
    }
privatestaticvoidcharBufferDemo2() throwsUnsupportedEncodingException {
byte[] byteArrayIn1="学无止境".getBytes("utf-16BE");
System.out.println(Charset.defaultCharset().name());
ByteBufferbyteBuffer=ByteBuffer.wrap(byteArrayIn1);
System.out.println("byteBuffer="+byteBuffer.getClass().getName());
CharBufferbuffer=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 (inti=0; i<buffer.capacity(); i++) {
System.out.print(buffer.get()+" ");
        }
    }
privatestaticvoidcharBufferDemo3() throwsUnsupportedEncodingException {
byte[] byteArrayIn1="学无止境".getBytes("utf-8");
System.out.println(Charset.defaultCharset().name());
ByteBufferbyteBuffer=ByteBuffer.wrap(byteArrayIn1);
System.out.println("byteBuffer="+byteBuffer.getClass().getName());
// CharBuffer buffer =byteBuffer.asCharBuffer();CharBufferbuffer=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 (inti=0; i<buffer.limit(); i++) {
System.out.print(buffer.get()+" ");
        }
    }
}

运行结果:

UTF-8byteBuffer=java.nio.HeapByteBuffercharBuffer=java.nio.ByteBufferAsCharBufferBbyteBuffer.postion=0byteBuffer.capacity=12byteBuffer.limit=126UTF-8byteBuffer=java.nio.HeapByteBuffercharBuffer=java.nio.ByteBufferAsCharBufferBbyteBuffer.postion=0byteBuffer.capacity=8byteBuffer.limit=84UTF-8byteBuffer=java.nio.HeapByteBuffercharBuffer=java.nio.HeapCharBufferbyteBuffer.postion=12byteBuffer.capacity=12byteBuffer.limit=1212

6.获取字节顺序:

/*** 设置与获得字节顺序:order()方法与字节数据排列顺序有关* ByteOrder order():获取此缓冲区的字节顺序*/publicclassByteBufferTest8 {
publicstaticvoidmain(String[] args) {
getOrder();
    }
privatestaticvoidgetOrder(){
intvalue=123456789;
ByteBufferbyteBuffer=ByteBuffer.allocate(4);
System.out.print(byteBuffer.order()+" ");
System.out.print(byteBuffer.order()+" ");
byteBuffer.putInt(value);
byte[] byteArray=byteBuffer.array();
for (inti=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 (inti=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 (inti=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()方法的作用:压缩此缓冲区,将缓冲区的当前位置和限制之间的字节复制到缓冲区的开始处*/publicclassByteBufferTest9 {
publicstaticvoidmain(String[] args) {
compactTest();
    }
privatestaticvoidcompactTest(){
ByteBufferbyteBuffer=ByteBuffer.wrap(newbyte[]{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 (inti=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进行比较*/publicclassByteBufferTest10 {
publicstaticvoidmain(String[] args) {
equalsMethod();
equalsMethods();
remainingEquals();
equalsMethod2();
compareToMethod();
compareToMethod2();
    }
privatestaticvoidcompareToMethod2() {
byte[] byteBufferIn1= {3,4,5};
byte[] byteBufferIn2= {1,2,3,4,5,6,7,8,9};
ByteBufferbyteBuffer1=ByteBuffer.wrap(byteBufferIn1);
ByteBufferbyteBuffer2=ByteBuffer.wrap(byteBufferIn2);
byteBuffer1.position(0);
byteBuffer2.position(2);
System.out.println("A="+byteBuffer1.compareTo(byteBuffer2));
    }
privatestaticvoidcompareToMethod() {
byte[] byteBufferIn1= {3,4,5};
byte[] byteBufferIn2= {1,2,3,104,5,6,7,8,9};
ByteBufferbyteBuffer1=ByteBuffer.wrap(byteBufferIn1);
ByteBufferbyteBuffer2=ByteBuffer.wrap(byteBufferIn2);
byteBuffer1.position(0);
byteBuffer2.position(2);
System.out.println("A="+byteBuffer1.compareTo(byteBuffer2));
    }
privatestaticvoidequalsMethod2() {
byte[] byteBufferIn1= {3,4,5};
byte[] byteBufferIn2= {1,2,3,4,5,6,7,8};
ByteBufferbyteBuffer1=ByteBuffer.wrap(byteBufferIn1);
ByteBufferbyteBuffer2=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());
    }
privatestaticvoidremainingEquals() {
byte[] byteArrayIn1= {3,4,5};
byte[] byteArrayIn2= {1,2,3,4,5,6,7,8};
ByteBufferbyteBuffer=ByteBuffer.wrap(byteArrayIn1);
ByteBufferbyteBuffer1=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());
    }
privatestaticvoidequalsMethods() {
byte[] byteArrayIn1= {1,2,3,4,5,6,7,8};
int[] intArrayIn2= {1,2,3,4,5,6,7,8};
ByteBufferbyteBuffer=ByteBuffer.wrap(byteArrayIn1);
IntBufferintBuffer=IntBuffer.wrap(intArrayIn2);
System.out.println("isEquals="+byteBuffer.equals(intBuffer));
    }
privatestaticvoidequalsMethod() {
byte[] byteBufferIn1= {1,2,3,4,5,6};
ByteBufferbyteBuffer=ByteBuffer.wrap(byteBufferIn1);
System.out.println("isEquals="+byteBuffer.equals(byteBuffer));
    }
}

运行结果:

isEquals=trueisEquals=falseA=falsebyteBuffer.remaining()=3byteBuffer1.remaining()=5A=trueBbyteBuffer1.remaining()=3CbyteBuffer2.remaining()=3D=falseEbyteBuffer1.remaining()=3FbyteBuffer2.remaining()=3A=-100A=-4

9.使用复制duplicate:

/*** 复制缓冲区:duplicate()*/publicclassByteBufferTest11 {
publicstaticvoidmain(String[] args) {
duplicateAndSlice();
duplicateMethod();
    }
privatestaticvoidduplicateMethod() {
byte[] byteBufferIn1= {1,2,3,4,5};
ByteBufferbyteBuffer1=ByteBuffer.wrap(byteBufferIn1);
ByteBufferbyteBuffer2=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 (inti=byteBuffer1.position(); i<byteBuffer1.limit(); i++) {
System.out.print(byteBuffer1.get(i)+" ");
        }
    }
privatestaticvoidduplicateAndSlice() {
byte[] byteBufferIn1= {1,2,3,4,5};
ByteBufferbyteBuffer1=ByteBuffer.wrap(byteBufferIn1);
byteBuffer1.position(2);
System.out.println("A capacity="+byteBuffer1.capacity()+" limit="+byteBuffer1.limit()+" postion="+byteBuffer1.position());
ByteBufferbyteBuffer2=byteBuffer1.slice();
ByteBufferbyteBuffer3=byteBuffer1.duplicate();
ByteBufferbyteBuffer4=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 (inti=byteBuffer2.position(); i<byteBuffer2.limit(); i++) {
System.out.print(byteBuffer2.get(i)+" ");
        }
System.out.println();
byteBuffer3.position(0);
for (inti=byteBuffer3.position(); i<byteBuffer3.limit(); i++) {
System.out.print(byteBuffer3.get(i)+" ");
        }
    }
}

运行结果:

Acapacity=5limit=5postion=2Bcapacity=3limit=3postion=0Ccapacity=5limit=5postion=234512345Acapacity=5limit=5postion=0Bcapacity=5limit=5postion=0Ccapacity=5limit=5postion=0Dcapacity=5limit=5postion=3byteBuffer2的位置是3,而byteBuffer1还是0,说明位置、限制和标记值是独立的122345

10.对ByteBuffer进行扩容:

/*** 对缓冲区进行扩容*/publicclassByteBufferTest12 {
publicstaticvoidmain(String[] args) {
byte[] byteBufferIn1= {1,2,3,4,5};
ByteBufferbyteBuffer1=ByteBuffer.wrap(byteBufferIn1);
ByteBufferbyteBuffer2=extendsSize(byteBuffer1,2);
byte[] newArray=byteBuffer2.array();
byteBuffer1.position(0);
for (inti=0; i<newArray.length; i++) {
System.out.print(newArray[i]+" ");
        }
    }
publicstaticByteBufferextendsSize(ByteBufferbuffer,intextendsSize){
ByteBuffernewByteBuffer=ByteBuffer.allocate(buffer.capacity()+extendsSize);
newByteBuffer.put(buffer);
returnnewByteBuffer;
    }
}

运行结果:

1 2 3 4 5 0 0

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

ByteBuffer就介绍到这里了,后面我们接着Channel的学习。

目录
相关文章
|
缓存 网络协议 Java
Java NIO学习(二):Channel通道
Java NIO 的通道类似流,但又有些不同:
144 0
Java NIO学习(二):Channel通道
|
设计模式 缓存 网络协议
Java NIO学习(一):Java NIO概述
IO 的操作方式通常分为几种:同步阻塞 BIO、同步非阻塞 NIO、异步非阻塞 AIO。
130 0
Java NIO学习(一):Java NIO概述
|
存储 缓存 Java
|
Java 测试技术 容器
NIO 下的 ByteBuffer简单学习
NIO 下的 ByteBuffer简单学习
99 0
|
NoSQL 应用服务中间件 Redis
NIO学习四-Selector
前面我们已经简单的学习了channel,知道channel作为通道,可以在通道中进行读写操作,同时知道ByteChannel是双向的。对于NIO的优势在于多路复用选择器上,在Nginx、Redis、Netty中都有多路复用的体现。因此学习Selector是有必要的。
66 0
NIO学习四-Selector
|
Java API
NIO学习三-Channel
在学习NIO时,ByteBuffer、Channel、Selector三个组件是必须了解的。前面我们说到ByteBuffer是作为缓冲区进行数据的存放或者获取。通常我们需要进行flip翻转操作,但是这个在Netty中,有一个更为强大的类可以替代ByteBuf,其不需要进行翻转,也可以进行读写的双向操作。要将数据打包到缓冲区中,通常需要使用通道,而通道作为传输数据的载体,也即它可以使数据从一端到另一端,因此就必须进行了解。 Channel中,我们也看到其子类有很多,通常都是用于读写操作的。其中ByteChannel可以进行读写操作,也即可以进行双向操作。 操作过程:首先创建流对象,有了流对象获取
62 0
NIO学习三-Channel
|
存储 索引
NIO学习一
NIO相比普通IO提供了功能更为强大、处理数据更快的解决方案。 常用于高性能服务器上。NIO实现高性能处理的原理是使用较少的线程来处理更多的任务 常规io使用的byte[]、char[]进行封装,而NIO采用ByteBuffer类来操作数据,再结合 针对File或socket技术的channel,采用同步非阻塞技术来实现高性能处理,而Netty 正是采用ByteBuffer(缓冲区)、Channel(通道)、Selector(选择器)进行封装的。 因此我们需要先了解NIO相关的知识。
84 0
NIO学习一
NIO同步非阻塞模型学习使用
NIO同步非阻塞模型学习使用
NIO同步非阻塞模型学习使用
【NIO】NIO三剑客之一ByteBuffer介绍与使用
【NIO】NIO三剑客之一ByteBuffer介绍与使用
【NIO】NIO三剑客之一ByteBuffer介绍与使用
|
存储 索引
Netty原理:ByteBuf对Nio bytebuffer做了什么导致效率提升?(2)
Netty原理:ByteBuf对Nio bytebuffer做了什么导致效率提升?(2)