1. ByteBuf淺層複製的高級使用方式
ByteBuf的淺層複製分爲兩種,有切片(slice)淺層複製和整體(duplicate)淺層複製。
1.1 slice切片淺層複製
ByteBuf的slice方法可以獲取到一個ByteBuf的一個切片。一個ByteBuf可以進行多次的切片淺層複製;多次切片後的ByteBuf對象可以共享一個存儲區域。
slice方法有兩個重載版本:
(1)public ByteBuf slice()
(2)public ByteBuf slice(int index, int length)第一個是不帶參數的slice方法,在內部是調用了第二個帶參數的slice方法.
- 代碼示例:
public class SliceTest {
@Test
public void testSlice() {
ByteBuf buffer = ByteBufAllocator.DEFAULT.buffer(9, 100);
print("動作:分配 ByteBuf(9, 100)", buffer);
buffer.writeBytes(new byte[]{1, 2, 3, 4});
print("動作:寫入4個字節 (1,2,3,4)", buffer);
ByteBuf slice = buffer.slice();
print("動作:切片 slice", slice);
}
}
- 返回的切片是一個新的ByteBuf對象,該對象的幾個重要屬性值
readerIndex(讀指針)的值爲0。
writerIndex(寫指針)的值爲源Bytebuf的readableBytes()可讀字節數。
maxCapacity(最大容量)的值爲源Bytebuf的readableBytes( )可讀字節數
· 切片不可以寫入,原因是:maxCapacity與writerIndex值相同。
· 切片和源ByteBuf的可讀字節數相同,原因是:切片後的可讀字節數爲自己的屬性writerIndex - readerIndex,也就是源ByteBuf的readableBytes() -0。
· 切片不會複製源ByteBuf的底層數據,底層數組和源ByteBuf的底層數組是同一個。
· 切片不會改變源ByteBuf的引用計數。
- slice()無參數方法所生成的切片就是源ByteBuf可讀部分的淺層複製。
- duplicate() 和slice() 方法都是淺層複製。不同的是,slice()方法是切取一段的淺層複製,而duplicate( )是整體的淺層複製。
- 淺層複製方法不會實際去複製數據,也不會改變ByteBuf的引用計數,這就會導致一個問題:在源ByteBuf調用release() 之後,一旦引用計數爲零,就變得不能訪問了;在這種場景下,源ByteBuf的所有淺層複製實例也不能進行讀寫了;如果強行對淺層複製實例進行讀寫,則會報錯。
- 淺層複製方法不會實際去複製數據,也不會改變ByteBuf的引用計數,這就會導致一個問題:在源ByteBuf調用release() 之後,一旦引用計數爲零,就變得不能訪問了;在這種場景下,源ByteBuf的所有淺層複製實例也不能進行讀寫了;如果強行對淺層複製實例進行讀寫,則會報錯。