ByteBuffer是个好东西,不过当中有一些稍显复杂的东西,现在简单总结一下。
先说一下我们的测试场景,首先分配一个ByteBuffer,然后写入100个数,然后把这100个数读出来,然后clear一下,准备下一次写入和读取。
首先是代码:
ByteBuffer buffer = ByteBuffer.allocate(256);
//system out
for (int i = 0; i < 100; i ++){
buffer.put((byte)1);
}
//system out
buffer.flip();
//system out
for (int i = 0; i < 100; i ++){
buffer.get();
}
//system out
buffer.clear();
//system out
然后是输出部分:
capacity=256 limit=256 position=0 //初始状态
capacity=256 limit=256 position=100 //写入100个数之后
capacity=256 limit=100 position=0 //flip之后
capacity=256 limit=100 position=100 //读取100个数之后
capacity=256 limit=256 position=0 //clear之后
capacity:代表当前buffer的大小,固定不变
limit:可读取限制和可写入限制
position:当前位置
这里面,flip函数有点不太好理解,貌似是翻转的意思,但是按照我的理解,这里的翻转,仅仅指的是从写入模式翻转到读取模式。这个模式的概念,是我自己加入的,加入这个之后,对ByteBuffer的理解和使用让我觉得舒服了很多。
初始状态下,ByteBuffer为写入模式,limit=256,代表着可以写入256个byte。
写入100个之后,limit=256不变,position=100,这个时候,我觉得写得差不多了,该读了。
那么flip一下,进入读取模式,limit=100,position=0,意味着,你可以从0开始,读100个数。
读完100个数之后,limit=100 position=100,
然后clear一下,重新进入写入模式limit=256 position=0。
这样理解以下,ByteBuffer瞬间就好理解多了!
事实上,在这里,个人认为,java本身自带的这个ByteBuffer,设计的并不是特别的理想;或者说,它的设计过于灵活了,让我们这些凡人并不能够很好的理解和使用。
如果大家对netty有所了解的话,会发现netty当中的ByteBuf其实是自己的一套实现机制,当中由于引入了readerindex和writerindex的概念,让netty的ByteBuf变得容易理解的多。