java - bytebuffer

来源:趣味经验馆 6.72K

<link rel="stylesheet" href="https://js.how234.com/third-party/SyntaxHighlighter/shCoreDefault.css" type="text/css" /><script type="text/javascript" src="https://js.how234.com/third-party/SyntaxHighlighter/shCore.js"></script><script type="text/javascript"> SyntaxHighlighter.all(); </script>

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的位置都是需要的数据。

java bytebuffer

这样以来也存在一个问题,当一次读到的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);   }

热门标签