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.

任意連續(xù)可用的序列,包含0或0個以上字節(jié)砰盐。此接口提供多個原始字節(jié)數(shù)組和NIO緩沖區(qū)的抽象視圖。

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的方法來創(chuàng)建緩沖區(qū),而非直接調用自己的構造函數(shù)。

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:

就像普通的原始字節(jié)數(shù)組,ByteBuf以0索引開始熊泵。這意味著第一個字節(jié)的索引總是0,而最后一個字節(jié)的索引總是(ByteBuf.capacity-1)甸昏。例如顽分,你要遍歷一個字符緩沖區(qū),你可以用下面這種方法施蜜,不論它的內部實現(xiàn)如何卒蘸。

 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 提供兩個指針變量來實現(xiàn)連續(xù)讀和寫操作 - readerIndex用于讀操作,writerIndex用于寫操作翻默。下圖顯示了緩沖區(qū)被兩個指針分成三個部分缸沃。

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.

可讀字符(實際內容)

這里是實際數(shù)據(jù)的存儲位置恰起。任何以"read"和"skip"開頭的操作會以當前的readerIndex上開始讀取或忽略指定數(shù)據(jù),讀取完畢后readerIndex增加趾牧。如果讀操作的參數(shù)也是ByteBuf村缸,且沒有指定目標索引,那么緩沖區(qū)的writerIndex也會隨之增加武氓。
如果沒有足夠的內容可讀梯皿,會拋出IndexOutOfBoundsException。新分配的县恕、被封裝的或拷貝的緩沖區(qū)的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開始寫數(shù)據(jù)忠烛,寫完后writerIndex增加属提。如果寫操作的參數(shù)也為ByteBuf,且沒有指定源索引美尸,那么緩沖區(qū)的readerIndex也會隨之增加冤议。
如果沒有足夠的可寫字節(jié),會拋出IndexOutOfBoundsException师坎。新分配的緩沖區(qū)的writerIndex默認值為0恕酸。封裝或拷貝的緩沖區(qū)的writerIndex默認值為緩沖區(qū)的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:

可廢棄字節(jié)

這部分包含已讀字節(jié)胯陋。初始化時蕊温,這部分的大小為0,但隨著讀操作的執(zhí)行遏乔,大小會達到writerIndex义矛。已讀字節(jié)可以通過調用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()后不能保證可讀字節(jié)的內容凉翻。可讀字節(jié)在大多數(shù)情況下不會被移除捻激,還可能會根據(jù)不同的底層的緩沖區(qū)實現(xiàn)填充不同的數(shù)據(jù)制轰。

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。它不會清空緩沖區(qū)的內容铺罢,而僅僅是清除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.

對于簡單的單字節(jié)搜索韭赘,使用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.

每個緩沖區(qū)有兩個標記索引脉漏,一個存儲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),創(chuàng)建一個已有緩沖區(qū)的視圖坦仍。衍生的緩沖區(qū)有獨立的readerIndex鳍烁,writerIndex,和標記索引繁扎,然而它們共享內部數(shù)據(jù)幔荒,就像NIO buffer。
防止全新地復制一個已存在的緩沖區(qū)梳玫,請用copy()替代爹梁。
還有,得到一個衍生的緩沖區(qū)不會調用retain()提澎,所以引用計數(shù)不會增加姚垃。

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.

字節(jié)數(shù)組

如果ByteBuf是字節(jié)數(shù)組,可以用array()方法直接轉換虱朵。判斷ByteBuf是否可以轉化為字節(jié)數(shù)組莉炉,可以用hasArray()來確認。

NIO緩沖區(qū)

如果一個ByteBuf可以轉化為包含一樣數(shù)據(jù)的NIO ByteBuffer碴犬,可以使用nioBuffer()來轉化。判斷ByteBuf是否可以轉化為NIO buffer梆暮,可以用nioBufferCount()來確認服协。

字符串

多種 toString(Charset)方法可將ByteBuf轉化為String。注意toString()不是轉化方法啦粹。

I/O流

參考ByteBufInputStream和ByteBufOutputStream

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末偿荷,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子唠椭,更是在濱河造成了極大的恐慌跳纳,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,332評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贪嫂,死亡現(xiàn)場離奇詭異寺庄,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,508評論 3 385
  • 文/潘曉璐 我一進店門斗塘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赢织,“玉大人,你說我怎么就攤上這事馍盟∮谥茫” “怎么了?”我有些...
    開封第一講書人閱讀 157,812評論 0 348
  • 文/不壞的土叔 我叫張陵贞岭,是天一觀的道長八毯。 經常有香客問我,道長瞄桨,這世上最難降的妖魔是什么话速? 我笑而不...
    開封第一講書人閱讀 56,607評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮讲婚,結果婚禮上尿孔,老公的妹妹穿的比我還像新娘。我一直安慰自己筹麸,他們只是感情好活合,可當我...
    茶點故事閱讀 65,728評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著物赶,像睡著了一般白指。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上酵紫,一...
    開封第一講書人閱讀 49,919評論 1 290
  • 那天告嘲,我揣著相機與錄音,去河邊找鬼奖地。 笑死橄唬,一個胖子當著我的面吹牛,可吹牛的內容都是我干的参歹。 我是一名探鬼主播仰楚,決...
    沈念sama閱讀 39,071評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼犬庇!你這毒婦竟也來了僧界?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,802評論 0 268
  • 序言:老撾萬榮一對情侶失蹤臭挽,失蹤者是張志新(化名)和其女友劉穎捂襟,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體欢峰,經...
    沈念sama閱讀 44,256評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡葬荷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,576評論 2 327
  • 正文 我和宋清朗相戀三年涨共,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闯狱。...
    茶點故事閱讀 38,712評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡煞赢,死狀恐怖,靈堂內的尸體忽然破棺而出哄孤,到底是詐尸還是另有隱情照筑,我是刑警寧澤,帶...
    沈念sama閱讀 34,389評論 4 332
  • 正文 年R本政府宣布瘦陈,位于F島的核電站凝危,受9級特大地震影響,放射性物質發(fā)生泄漏晨逝。R本人自食惡果不足惜蛾默,卻給世界環(huán)境...
    茶點故事閱讀 40,032評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望捉貌。 院中可真熱鬧支鸡,春花似錦、人聲如沸趁窃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽醒陆。三九已至瀑构,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間刨摩,已是汗流浹背寺晌。 一陣腳步聲響...
    開封第一講書人閱讀 32,026評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留澡刹,地道東北人呻征。 一個月前我還...
    沈念sama閱讀 46,473評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像罢浇,于是被迫代替她去往敵國和親怕犁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,606評論 2 350