Skip to content

Commit a06086c

Browse files
committed
增加:ByteBuf字节访问
1 parent 398de83 commit a06086c

7 files changed

+64
-0
lines changed

img/netty/ByteBuf内部分段.png

30.8 KB
Loading

img/netty/ByteBuf的clear方法.png

6.63 KB
Loading
19.3 KB
Loading
27 KB
Loading
Loading

img/netty/随机访问索引.png

17.1 KB
Loading

netty-learning/ByteBuf.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,67 @@ ByteBuf有多种使用模式,我们可以根据需求构建不同使用模式
7777

7878
![复合缓冲区模式](../img/netty/复合缓冲区模式.png)
7979

80+
81+
### 字节级别的操作
82+
除了普通的读写操作,ByteBuf还提供了修改数据的方法。
83+
84+
85+
#### 索引访问
86+
如数组的索引访问一样,ByteBuf的索引访问也是从零开始的,第一个字节的索引是0,最后一个字节的索引总是
87+
capacity - 1:
88+
89+
![随机访问索引](../img/netty/随机访问索引.png)
90+
91+
注意:使用getByte方式访问,既不会改变readerIndex,也不会改变writerIndex。
92+
93+
JDK的ByteBuffer只有一个索引position,所以当ByteBuffer在读和写模式之间切换时,需要使用flip方法。
94+
而ByteBuf同时具有读索引和写索引,则无需切换模式,在ByteBuf内部,其索引满足:
95+
96+
````text
97+
0 <= readerIndex <= writerIndex <= capacity
98+
````
99+
100+
这样的规律,当使用readerIndex读取字节,或使用writerIndex写入字节时,ByteBuf内部的分段大致如下:
101+
102+
![ByteBuf内部分段](../img/netty/ByteBuf内部分段.png)
103+
104+
上图介绍了在ByteBuf内部大致有3个分段,接下来我们就详细的介绍下这三个分段。
105+
106+
107+
#### 可丢弃字节
108+
上图中,当readerIndex读取一部分字节后,之前读过的字节就属于已读字节,可以被丢弃了,通过调用
109+
ByteBuf的discardReadBytes方法我们可以丢弃这个分段,丢弃这个分段实际上是删除这个分段的已读字节,
110+
然后回收这部分空间:
111+
112+
![DiscardReadBytes回收后ByteBuf内部分段](../img/netty/DiscardReadBytes回收后ByteBuf内部分段.png)
113+
114+
115+
#### 可读字节
116+
ByteBuf的可读字节分段存储了尚未读取的字节,我们可以使用readBytes等方法来读取这部分数据,如果我们读取
117+
的范围超过了可读字节分段,那么ByteBuf会抛出IndexOutOfBoundsException异常,所以在读取数据之前,我们
118+
需要使用isReadable方法判断是否仍然有可读字节分段。
119+
120+
121+
#### 可写字节
122+
可写字节分段即没有被写入数据的区域,我们可以使用writeBytes等方法向可写字节分段写入数据,如果我们写入
123+
的字节超过了ByteBuf的容量,那么ByteBuf也会抛出IndexOutOfBoundsException异常。
124+
125+
126+
#### 索引管理
127+
我们可以通过markReaderIndex,markWriterIndex方法来标记当前readerIndex和writerIndex的位置,
128+
然后使用resetReaderIndex,resetWriterIndex方法来将readerIndex和writerIndex重置为之前标记过的
129+
位置。
130+
131+
我们还可以使用clear方法来将readerIndex和writerIndex重置为0,但是clear方法并不会清空ByteBuf的
132+
内容,下面clear方法的实现:
133+
134+
![ByteBuf的clear方法](../img/netty/ByteBuf的clear方法.png)
135+
136+
其过程是这样的:
137+
138+
![ByteBuf的clear方法调用前](../img/netty/ByteBuf的clear方法调用前.png)
139+
140+
![ByteBuf的clear方法调用后](../img/netty/ByteBuf的clear方法调用后.png)
141+
142+
由于调用clear后,数据并没有被清空,但整个ByteBuf仍然是可写的,这比discardReadBytes轻量的多,
143+
DiscardReadBytes还要回收已读字节空间。

0 commit comments

Comments
 (0)