一. ByteBufAllocator 池類 可分配基於堆的或者直接內存的ByteBuf 得到ByteBufAllocator引用的的兩種方式: channel.alloc(); ctx.alloc(); ByteBufAllocator的兩種實現: PooledByteBufAllocator UnpooledByteBufAllocator 二.Unpooled 非池化的Bytebuf 三.ByteBufUtil
ByteBuf的主要有讀寫兩個指針,這是他比原生ByteBuffer方便和易於理解的地方 read*, write開頭的方法會改變索引,可是set將不會改變索引位置 |**** 版本號 4個字節的長度 具體的內容****|數組
因此能夠經過hasArray判斷是否支持數組
ByteBuf heapBuf = ...; if (heapBuf.hasArray()) { //1 byte[] array = heapBuf.array(); //2 int offset = heapBuf.arrayOffset() + heapBuf.readerIndex(); //3 int length = heapBuf.readableBytes();//4 handleArray(array, offset, length); //5 }
ByteBuf directBuf = ... if (!directBuf.hasArray()) { //1 int length = directBuf.readableBytes();//2 byte[] array = new byte[length]; //3 directBuf.getBytes(directBuf.readerIndex(), array); //4 handleArray(array, 0, length); //5 }
複合緩衝區(CompositeByteBuf )指針
hasArray始終返回false
CompositeByteBuf messageBuf = ...; ByteBuf headerBuf = ...; // 能夠支持或直接 ByteBuf bodyBuf = ...; // 能夠支持或直接 messageBuf.addComponents(headerBuf, bodyBuf); // .... messageBuf.removeComponent(0); // 移除頭 //2 for (int i = 0; i < messageBuf.numComponents(); i++) { //3 System.out.println(messageBuf.component(i).toString()); }
訪問數據 CompositeByteBuf compBuf = ...; int length = compBuf.readableBytes(); //1 byte[] array = new byte[length]; //2 compBuf.getBytes(compBuf.readerIndex(), array); //3 handleArray(array, 0, length); //4
隨機訪問索引: 如getByte,不會改變索引 可丟棄的字節從新利用: discardReadBytes(); 索引操做: markWriterIndex() markReaderIndex() resetReaderIndex() resetWriterIndex() clear() 比 discardReadBytes()成本更低 查詢操做: forEachByte int index = buffer.forEachByte(ByteBufProcessor.FIND_CR); forEachByte(ByteBufProcessor.FIND_NUL) 衍生的緩衝區: 表明一個專門的展現 ByteBuf 內容的「視圖" 這種視圖由下面幾種方法產生 duplicate(), slice(), slice(int, int),readOnly(),order(ByteOrder) 這種視圖和源是數據共享的嗎? 讀寫索引是同樣的嗎? 標記索引是同樣的嗎? 答:都是共享的code
拷貝: copy()和copy(int, int) 這個副本是獨立的, 和源數據不共享 須要某段數據: slice(int, int) 和源數據是共享的 讀寫操做: set寫入/get讀取不會改變索引 write/readcomponent