Buffer#Capacity,Position 和 Limit
Buffer本质上一个能读写的 内存块 ,在Java中被包装成一个 NIO Buffer 对象。Buffer的3个属性
- capacity
- position
- limit
分别对应buffer的容量,读写的位置,能够读写的最大值.
写模式下, position代表当前写入的位置,limit代表写入的最大量,一般等于capacity
读模式下,position代表当前读取的位置,limit代表能够读取的最大量,相当于写模式下position的位置。
借用一幅图表示

Buffer capacity, position and limit in write and read mode.
PS:容量的大小是确定的,在容量满时需要清空才能再次写入 ,
Netty提供了可扩容的Buffer.
filp,slice,和duplicate
- filp: 英文翻译为反转
- slice: 切片
- duplicate: 复制
filp 用于切换 读写模式 . 创建Buffer时是写入模式,读取时需要切换才能进行读取. 切换时主要变更 Buffer的position和limit.
public class Test {public static void main(String[] args) {ByteBuffer allocate = ByteBuffer.allocate(16);allocate.putInt(1);allocate.flip();System.out.println(allocate.getInt());}}
slice 创建一个Buffer , 共享 父Buffer 的内容, 在 slice 中的修改会直接反馈在 父Buffer中, Position,Limit,capacity 相互独立.
主要在不切换父Buffer时使用 , 在 RocketMq 中出现该使用方式
public class SliceTest {public static void main(String[] args) {ByteBuffer allocate = ByteBuffer.allocate(16);//切片1ByteBuffer slice = allocate.slice();slice.position(0);slice.putInt(1);//切片2ByteBuffer two = allocate.slice();two.position(4);two.putInt(2);System.out.println(allocate.getInt());//输出1System.out.println(allocate.getInt());//输出2}}
创建的ByteBuffer没有直接使用,而是通过共享的slice去进行修改,slice的修改会直接反馈在allocate的内容当中,省去了 filp . 避免了忘记 filp 的错误.
duplicate 复制一个Buffer ,所有的数据和父Buffer保持一致,3个属性值项目独立.
public class DuplicateTest {public static void main(String[] args) {ByteBuffer allocate = ByteBuffer.allocate(16);allocate.putInt(1);ByteBuffer duplicate = allocate.duplicate();//复制bufferallocate.putInt(2);duplicate.flip();System.out.println(duplicate.getInt());//输出1System.out.println(duplicate.getInt());//输出2}}
读写示例
通过 slice 写入,不需要通过 filp ,后读取数据. 限于篇幅贴了部分代码 ,代码地址 MessageWrite.java
public class MessageWrite {public static void main(String[] args) throws Exception {ByteBuffer map = ByteBuffer.allocate(1024);AtomicInteger at = new AtomicInteger(0);ByteBuffer byteBuffer = map.slice();byteBuffer.position(at.get());Message message = new Message();message.setBody("我为人人,人人为我".getBytes());message.setTopic("chenshun00");message.setProperties(new HashMap<String, String>() {{this.put("11", "11");this.put("22", "22");this.put("33", "33");}});at.set(writeMessage(message, byteBuffer));Message read = read(map);System.out.println(read.id);System.out.println(read.getProperties().toString());System.out.println(read.getTopic());System.out.println(new String(read.getBody()));}public static int writeMessage(Message message, ByteBuffer byteBuffer) {return 0;}public static Message read(ByteBuffer byteBuffer) {return null;}private static String toStr(Map<String, String> xx) {return JSONObject.toJSONString(xx);}private static Map<String, String> toMap(String json) {return JSON.parseObject(json, new TypeReference<HashMap<String, String>>() {});}}
