Class ByteBuf

官方文档:

Class ByteBuf ------------------ Netty API Reference (4.0.54.Final)

A random and sequential accessible sequence of zero or more bytes (octets). This interface provides an abstract view for one or more primitive byte arrays (byte[]) and NIO buffers.

任意连续可用的序列,包含0或0个以上字节。此接口提供多个原始字节数组和NIO缓冲区的抽象视图。

Creation of a buffer

It is recommended to create a new buffer using the helper methods in Unpooled rather than calling an individual implementation's constructor.

强烈建议用帮助类Unpooled的方法来创建缓冲区,而非直接调用自己的构造函数。

Random Access Indexing

Just like an ordinary primitive byte array, ByteBuf uses zero-based indexing. It means the index of the first byte is always 0 and the index of the last byte is always capacity - 1. For example, to iterate all bytes of a buffer, you can do the following, regardless of its internal implementation:

就像普通的原始字节数组,ByteBuf以0索引开始。这意味着第一个字节的索引总是0,而最后一个字节的索引总是(ByteBuf.capacity-1)。例如,你要遍历一个字符缓冲区,你可以用下面这种方法,不论它的内部实现如何。

 ByteBuf buffer = ...;
 for (int i = 0; i < buffer.capacity(); i ++) {
     byte b = buffer.getByte(i);
     System.out.println((char) b);
 }

Sequential Access Indexing

ByteBuf provides two pointer variables to support sequential read and write operations - readerIndex for a read operation and writerIndex for a write operation respectively. The following diagram shows how a buffer is segmented into three areas by the two pointers:

ByteBuf 提供两个指针变量来实现连续读和写操作 - readerIndex用于读操作,writerIndex用于写操作。下图显示了缓冲区被两个指针分成三个部分。

Readable bytes (the actual content)

This segment is where the actual data is stored. Any operation whose name starts with read or skip will get or skip the data at the current readerIndex and increase it by the number of read bytes. If the argument of the read operation is also a ByteBuf and no destination index is specified, the specified buffer's writerIndex is increased together.
If there's not enough content left, IndexOutOfBoundsException is raised. The default value of newly allocated, wrapped or copied buffer's readerIndex is 0.

可读字符(实际内容)

这里是实际数据的存储位置。任何以"read"和"skip"开头的操作会以当前的readerIndex上开始读取或忽略指定数据,读取完毕后readerIndex增加。如果读操作的参数也是ByteBuf,且没有指定目标索引,那么缓冲区的writerIndex也会随之增加。
如果没有足够的内容可读,会抛出IndexOutOfBoundsException。新分配的、被封装的或拷贝的缓冲区的readerIndex默认值为0。

// Iterates the readable bytes of a buffer.

 ByteBuf buffer = ...;
 while (buffer.isReadable()) {
     System.out.println(buffer.readByte());
 }
Writable bytes

This segment is a undefined space which needs to be filled. Any operation whose name starts with write will write the data at the current writerIndex and increase it by the number of written bytes. If the argument of the write operation is also a ByteBuf, and no source index is specified, the specified buffer's readerIndex is increased together.
If there's not enough writable bytes left, IndexOutOfBoundsException is raised. The default value of newly allocated buffer's writerIndex is 0. The default value of wrapped or copied buffer's writerIndex is the capacity of the buffer.

可写字符

这里是要被填充的被定义空间。任何以"write"开头的操作会以当前writerIndex开始写数据,写完后writerIndex增加。如果写操作的参数也为ByteBuf,且没有指定源索引,那么缓冲区的readerIndex也会随之增加。
如果没有足够的可写字节,会抛出IndexOutOfBoundsException。新分配的缓冲区的writerIndex默认值为0。封装或拷贝的缓冲区的writerIndex默认值为缓冲区的capacity。

// Fills the writable bytes of a buffer with random integers.

ByteBuf buffer = ...;
 while (buffer.maxWritableBytes() >= 4) {
     buffer.writeInt(random.nextInt());
 }
Discardable bytes

This segment contains the bytes which were read already by a read operation. Initially, the size of this segment is 0, but its size increases up to the writerIndex as read operations are executed. The read bytes can be discarded by calling discardReadBytes() to reclaim unused area as depicted by the following diagram:

可废弃字节

这部分包含已读字节。初始化时,这部分的大小为0,但随着读操作的执行,大小会达到writerIndex。已读字节可以通过调用discardReadBytes()废弃,回收可用的空间。下图描述了这个过程

Please note that there is no guarantee about the content of writable bytes after calling discardReadBytes(). The writable bytes will not be moved in most cases and could even be filled with completely different data depending on the underlying buffer implementation.

请注意调用discardReadBytes()后不能保证可读字节的内容。可读字节在大多数情况下不会被移除,还可能会根据不同的底层的缓冲区实现填充不同的数据。

Clearing the buffer indexes

You can set both readerIndex and writerIndex to 0 by calling clear(). It does not clear the buffer content (e.g. filling with 0) but just clears the two pointers. Please also note that the semantic of this operation is different from Buffer.clear().

你可以调用clear()把readerIndex和writerIndex设置为0。它不会清空缓冲区的内容,而仅仅是清除2个指针。请注意这个操作和Buffer.clear()在语义上的不同。

Search operations

For simple single-byte searches, use indexOf(int, int, byte) and bytesBefore(int, int, byte). bytesBefore(byte) is especially useful when you deal with a NUL-terminated string. For complicated searches, use forEachByte(int, int, ByteBufProcessor) with a ByteBufProcessor implementation.

对于简单的单字节搜索,使用indexof(int, int, byte)和bytesBefore(int, int, byte)。bytesBefore(byte)在处理以NUL结尾的字符串时特别有效。对于复杂字符的搜索,使用forEachByte(int, int, ByteBufProcessor)

Mark and reset

There are two marker indexes in every buffer. One is for storing readerIndex and the other is for storing writerIndex. You can always reposition one of the two indexes by calling a reset method. It works in a similar fashion to the mark and reset methods in InputStream except that there's no readlimit.

每个缓冲区有两个标记索引,一个存储readerIndex,另一个存储writerIndex。你总是可以调用reset方法来复位其中一个索引。标记和重置方法在输入流中以相同的方式处理,只不过没有readlimit(读限制)罢了。

Derived buffers

You can create a view of an existing buffer by calling either duplicate(), slice() or slice(int, int). A derived buffer will have an independent readerIndex, writerIndex and marker indexes, while it shares other internal data representation, just like a NIO buffer does.
In case a completely fresh copy of an existing buffer is required, please call copy() method instead.
Also be aware that obtaining derived buffers will NOT call retain() and so the reference count will NOT be increased.

你可以通过调用duplicate()、slice()、或者slice(int, int),创建一个已有缓冲区的视图。衍生的缓冲区有独立的readerIndex,writerIndex,和标记索引,然而它们共享内部数据,就像NIO buffer。
防止全新地复制一个已存在的缓冲区,请用copy()替代。
还有,得到一个衍生的缓冲区不会调用retain(),所以引用计数不会增加。

Conversion to existing JDK types

Byte array

If a ByteBuf is backed by a byte array (i.e. byte[]), you can access it directly via the array() method. To determine if a buffer is backed by a byte array, hasArray() should be used.

NIO Buffers

If a ByteBuf can be converted into an NIO ByteBuffer which shares its content (i.e. view buffer), you can get it via the nioBuffer() method. To determine if a buffer can be converted into an NIO buffer, use nioBufferCount().

Strings

Various toString(Charset) methods convert a ByteBuf into a String. Please note that toString() is not a conversion method.

I/O Streams

Please refer to ByteBufInputStream and ByteBufOutputStream.

字节数组

如果ByteBuf是字节数组,可以用array()方法直接转换。判断ByteBuf是否可以转化为字节数组,可以用hasArray()来确认。

NIO缓冲区

如果一个ByteBuf可以转化为包含一样数据的NIO ByteBuffer,可以使用nioBuffer()来转化。判断ByteBuf是否可以转化为NIO buffer,可以用nioBufferCount()来确认。

字符串

多种 toString(Charset)方法可将ByteBuf转化为String。注意toString()不是转化方法。

I/O流

参考ByteBufInputStream和ByteBufOutputStream

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,681评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,710评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,623评论 0 334
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,202评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,232评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,368评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,795评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,461评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,647评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,476评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,525评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,226评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,785评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,857评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,090评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,647评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,215评论 2 341