java bytebuffer是什么,让我们一起了解一下?
bytebuffer是buffer缓冲区的一种,看作提供了一些(未定义的)底层字节存储的视图,需要注意的是几个操作的影响:flip(),clear(),rewind(),还有就是在读取或者写入时,标志的变化。
比如get()方法导致position加1,SocketChannel采用的是非阻塞异步读取流数据,在读取的时候,通常是如下代码示例:
ByteBuffer.clear(); SocketChannel.read(ByteBuffer);
如果流中有数据,就会把数据从position开始读到ByteBuffer中,在读取之前ByteBuffer的clear操作会把position置为0,limit置为capability,也就是相当于清空了之前的内容,但是ByteBuffer中数组的内容在read之前是没有改变的。
read之后,通常就是开始从ByteBuffer中提取读到的数据,如果你的数据是以自己定义的数据包的格式进行发送的,那你还需要判断是否读到了数据包的结尾,因为对流数据本身来说是没有结尾这一说的。在提取数据之前,要先把position放到开始读取时的位置,把limit放到当前位置,所以要flip一下,表示从position到limit的位置都是需要的数据。
这样以来也存在一个问题,当一次读到的ByteBuffer不包含完整的数据包或者包含多个数据包,那么就需要在下一次继续把这些包分拆出来。
另外一个可能会用到的操作就是ByteBuffer.rewind(),他会把position置为0,limit保持不变,可以用于重复读取一段数据。
实战操作:
ByteBuffer类提供了4个静态工厂方法来获得ByteBuffer的实例:
1、allocate(int capacity):从堆空间中分配一个容量大小为capacity的byte数组作为缓冲区的byte数据存储器。
2、allocateDirect(int capacity):是不使用JVM堆栈而是通过操作系统来创建内存块用作缓冲区,它与当前操作系统能够更好的耦合,因此能进一步提高I/O操作速度。但是分配直接缓冲区的系统开销很大,因此只有在缓冲区较大并长期存在,或者需要经常重用时,才使用这种缓冲区。
3、wrap(byte[] array):这个缓冲区的数据会存放在byte数组中,bytes数组或buff缓冲区任何一方中数据的改动都会影响另一方。其实ByteBuffer底层本来就有一个bytes数组负责来保存buffer缓冲区中的数据,通过allocate方法系统会帮你构造一个byte数组。
4、wrap(byte[] array,int offset, int length):在上一个方法的基础上可以指定偏移量和长度,这个offset也就是包装后byteBuffer的position,而length呢就是limit-position的大小,从而我们可以得到limit的位置为length+position(offset)。
测试方法:
public static void main(String args[]) throws FileNotFoundException { System.out.println("----------Test allocate--------"); System.out.println("before alocate:" + Runtime.getRuntime().freeMemory()); // 如果分配的内存过小,调用Runtime.getRuntime().freeMemory()大小不会变化? // 要超过多少内存大小JVM才能感觉到? ByteBuffer buffer = ByteBuffer.allocate(102400); System.out.println("buffer = " + buffer); System.out.println("after alocate:" + Runtime.getRuntime().freeMemory()); // 这部分直接用的系统内存,所以对JVM的内存没有影响 ByteBuffer directBuffer = ByteBuffer.allocateDirect(102400); System.out.println("directBuffer = " + directBuffer); System.out.println("after direct alocate:" + Runtime.getRuntime().freeMemory()); System.out.println("----------Test wrap--------"); byte[] bytes = new byte[32]; buffer = ByteBuffer.wrap(bytes); System.out.println(buffer); buffer = ByteBuffer.wrap(bytes, 10, 10); System.out.println(buffer); }
以上就是小编今天的分享了,希望可以帮助到大家。