国产gaysexchina男同gay,japanrcep老熟妇乱子伦视频,吃奶呻吟打开双腿做受动态图,成人色网站,国产av一区二区三区最新精品

Netty字節(jié)級別的操作

2020-11-11 09:03 更新

除了基本的讀寫操作, ByteBuf 還提供了它所包含的數(shù)據(jù)的修改方法。

隨機訪問索引

ByteBuf 使用zero-based 的 indexing(從0開始的索引),第一個字節(jié)的索引是 0,最后一個字節(jié)的索引是 ByteBuf 的 capacity - 1,下面代碼是遍歷 ByteBuf 的所有字節(jié):

Listing 5.6 Access data

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

注意通過索引訪問時不會推進 readerIndex (讀索引)和 writerIndex(寫索引),我們可以通過 ByteBuf 的 readerIndex(index) 或 writerIndex(index) 來分別推進讀索引或寫索引

順序訪問索引

ByteBuf 提供兩個指針變量支付讀和寫操作,讀操作是使用 readerIndex(),寫操作時使用 writerIndex()。這和JDK的ByteBuffer不同,ByteBuffer只有一個方法來設置索引,所以需要使用 flip() 方法來切換讀和寫模式。

ByteBuf 一定符合:0 <= readerIndex <= writerIndex <= capacity。

Figure 5.3 ByteBuf internal segmentation

Figure%205

1.字節(jié),可以被丟棄,因為它們已經(jīng)被讀

2.還沒有被讀的字節(jié)是:“readable bytes(可讀字節(jié))”

3.空間可加入多個字節(jié)的是:“writeable bytes(寫字節(jié))”

可丟棄字節(jié)的字節(jié)

標有“可丟棄字節(jié)”的段包含已經(jīng)被讀取的字節(jié)。他們可以被丟棄,通過調(diào)用discardReadBytes() 來回收空間。這個段的初始大小存儲在readerIndex,為 0,當“read”操作被執(zhí)行時遞增(“get”操作不會移動 readerIndex)。

圖5.4示出了在 圖5.3 中的緩沖區(qū)中調(diào)用 discardReadBytes() 所示的結果。你可以看到,在丟棄字節(jié)段的空間已變得可用寫。需要注意的是不能保證對可寫的段之后的內(nèi)容在 discardReadBytes() 方法之后已經(jīng)被調(diào)用。

Figure 5.4 ByteBuf after discarding read bytes.

Figure%205

1.字節(jié)尚未被讀出(readerIndex 現(xiàn)在 0)。 2.可用的空間,由于空間被回收而增大。

ByteBuf.discardReadBytes() 可以用來清空 ByteBuf 中已讀取的數(shù)據(jù),從而使 ByteBuf 有多余的空間容納新的數(shù)據(jù),但是discardReadBytes() 可能會涉及內(nèi)存復制,因為它需要移動 ByteBuf 中可讀的字節(jié)到開始位置,這樣的操作會影響性能,一般在需要馬上釋放內(nèi)存的時候使用收益會比較大。

可讀字節(jié)

ByteBuf 的“可讀字節(jié)”分段存儲的是實際數(shù)據(jù)。新分配,包裝,或復制的緩沖區(qū)的 readerIndex 的默認值為 0 。任何操作,其名稱以 "read" 或 "skip" 開頭的都將檢索或跳過該數(shù)據(jù)在當前 readerIndex ,并且通過讀取的字節(jié)數(shù)來遞增。

如果所謂的讀操作是一個指定 ByteBuf 參數(shù)作為寫入的對象,并且沒有一個目標索引參數(shù),目標緩沖區(qū)的 writerIndex 也會增加了。例如:

readBytes(ByteBuf dest);

如果試圖從緩沖器讀取已經(jīng)用盡的可讀的字節(jié),則拋出IndexOutOfBoundsException。清單5.8顯示了如何讀取所有可讀字節(jié)。

Listing 5.7 Read all data

//遍歷緩沖區(qū)的可讀字節(jié)
ByteBuf buffer= ...;
while (buffer.isReadable()) {
    System.out.println(buffer.readByte());
}

這段是未定義內(nèi)容的地方,準備好寫。一個新分配的緩沖區(qū)的 writerIndex 的默認值是 0 。任何操作,其名稱 "write"開頭的操作在當前的 writerIndex 寫入數(shù)據(jù)時,遞增字節(jié)寫入的數(shù)量。如果寫操作的目標也是 ByteBuf ,且未指定源索引,則源緩沖區(qū)的 readerIndex 將增加相同的量。例如:

writeBytes(ByteBuf dest);

如果試圖寫入超出目標的容量,則拋出 IndexOutOfBoundException。

下面的例子展示了填充隨機整數(shù)到緩沖區(qū)中,直到耗盡空間。該方法writableBytes() 被用在這里確定是否存在足夠的緩沖空間。

Listing 5.8 Write data

//填充隨機整數(shù)到緩沖區(qū)中
ByteBuf buffer = ...;
while (buffer.writableBytes() >= 4) {
    buffer.writeInt(random.nextInt());
}

索引管理

在 JDK 的 InputStream 定義了 mark(int readlimit) 和 reset()方法。這些是分別用來標記流中的當前位置和復位流到該位置。

同樣,您可以設置和重新定位ByteBuf readerIndex 和 writerIndex 通過調(diào)用 markReaderIndex(), markWriterIndex(), resetReaderIndex() 和 resetWriterIndex()。這些類似于InputStream 的調(diào)用,所不同的是,沒有 readlimit 參數(shù)來指定當標志變?yōu)闊o效。

您也可以通過調(diào)用 readerIndex(int) 或 writerIndex(int) 將指標移動到指定的位置。在嘗試任何無效位置上設置一個索引將導致 IndexOutOfBoundsException 異常。

調(diào)用 clear() 可以同時設置 readerIndex 和 writerIndex 為 0。注意,這不會清除內(nèi)存中的內(nèi)容。讓我們看看它是如何工作的。 (圖5.5圖重復5.3 )

Figure 5.5 Before clear() is called

Figure%205

調(diào)用之前,包含3個段,下面顯示了調(diào)用之后

Figure 5.6 After clear() is called

Figure%205

現(xiàn)在 整個 ByteBuf 空間都是可寫的了。

clear() 比 discardReadBytes() 更低成本,因為他只是重置了索引,而沒有內(nèi)存拷貝。

查詢操作

有幾種方法,以確定在所述緩沖器中的指定值的索引。最簡單的是使用 indexOf() 方法。更復雜的搜索執(zhí)行以 ByteBufProcessor 為參數(shù)的方法。這個接口定義了一個方法,boolean process(byte value),它用來報告輸入值是否是一個正在尋求的值。

ByteBufProcessor 定義了很多方便實現(xiàn)共同目標值。例如,假設您的應用程序需要集成所謂的“Flash sockets”,將使用 NULL 結尾的內(nèi)容。調(diào)用

forEachByte(ByteBufProcessor.FIND_NUL)

通過減少的,因為少量的 “邊界檢查”的處理過程中執(zhí)行了,從而使 消耗 Flash 數(shù)據(jù)變得 編碼工作量更少、效率更高。

下面例子展示了尋找一個回車符,\ r的一個例子。

Listing 5.9 Using ByteBufProcessor to find \r

ByteBuf buffer = ...;
int index = buffer.forEachByte(ByteBufProcessor.FIND_CR);

衍生的緩沖區(qū)

“衍生的緩沖區(qū)”是代表一個專門的展示 ByteBuf 內(nèi)容的“視圖”。這種視圖是由 duplicate(), slice(), slice(int, int),readOnly(), 和 order(ByteOrder) 方法創(chuàng)建的。所有這些都返回一個新的 ByteBuf 實例包括它自己的 reader, writer 和標記索引。然而,內(nèi)部數(shù)據(jù)存儲共享就像在一個 NIO 的 ByteBuffer。這使得衍生的緩沖區(qū)創(chuàng)建、修改其 內(nèi)容,以及修改其“源”實例更廉價。

ByteBuf 拷貝

如果需要已有的緩沖區(qū)的全新副本,使用 copy() 或者 copy(int, int)。不同于派生緩沖區(qū),這個調(diào)用返回的 ByteBuf 有數(shù)據(jù)的獨立副本。

若需要操作某段數(shù)據(jù),使用 slice(int, int),下面展示了用法:

Listing 5.10 Slice a ByteBuf

Charset utf8 = Charset.forName("UTF-8");
ByteBuf buf = Unpooled.copiedBuffer("Netty in Action rocks!", utf8); //1

ByteBuf sliced = buf.slice(0, 14);          //2
System.out.println(sliced.toString(utf8));  //3

buf.setByte(0, (byte) 'J');                 //4
assert buf.getByte(0) == sliced.getByte(0);

1.創(chuàng)建一個 ByteBuf 保存特定字節(jié)串。

2.創(chuàng)建從索引 0 開始,并在 14 結束的 ByteBuf 的新 slice。

3.打印 Netty in Action

4.更新索引 0 的字節(jié)。

5.斷言成功,因為數(shù)據(jù)是共享的,并以一個地方所做的修改將在其他地方可見。

下面看下如何將一個 ByteBuf 段的副本不同于 slice。

Listing 5.11 Copying a ByteBuf

Charset utf8 = Charset.forName("UTF-8");
ByteBuf buf = Unpooled.copiedBuffer("Netty in Action rocks!", utf8);     //1

ByteBuf copy = buf.copy(0, 14);               //2
System.out.println(copy.toString(utf8));      //3

buf.setByte(0, (byte) 'J');                   //4
assert buf.getByte(0) != copy.getByte(0);

1.創(chuàng)建一個 ByteBuf 保存特定字節(jié)串。

2.創(chuàng)建從索引0開始和 14 結束 的 ByteBuf 的段的拷貝。

3.打印 Netty in Action

4.更新索引 0 的字節(jié)。

5.斷言成功,因為數(shù)據(jù)不是共享的,并以一個地方所做的修改將不影響其他。

代碼幾乎是相同的,但所 衍生的 ByteBuf 效果是不同的。因此,使用一個 slice 可以盡可能避免復制內(nèi)存。

讀/寫操作

讀/寫操作主要由2類:

  • get()/set() 操作從給定的索引開始,保持不變
  • read()/write() 操作從給定的索引開始,與字節(jié)訪問的數(shù)量來適用,遞增當前的寫索引或讀索引

ByteBuf 的各種讀寫方法或其他一些檢查方法可以看 ByteBuf 的 API,下面是常見的 get() 操作:

Table 5.1 get() operations

方法名稱描述
getBoolean(int)返回當前索引的 Boolean 值
getByte(int) getUnsignedByte(int)返回當前索引的(無符號)字節(jié)
getMedium(int) getUnsignedMedium(int)返回當前索引的 (無符號) 24-bit 中間值
getInt(int) getUnsignedInt(int)返回當前索引的(無符號) 整型
getLong(int) getUnsignedLong(int)返回當前索引的 (無符號) Long 型
getShort(int) getUnsignedShort(int)返回當前索引的 (無符號) Short 型
getBytes(int, ...)字節(jié)

常見 set() 操作如下

Table 5.2 set() operations

方法名稱描述
setBoolean(int, boolean)在指定的索引位置設置 Boolean 值
setByte(int, int)在指定的索引位置設置 byte 值
setMedium(int, int)在指定的索引位置設置 24-bit 中間 值
setInt(int, int)在指定的索引位置設置 int 值
setLong(int, long)在指定的索引位置設置 long 值
setShort(int, int)在指定的索引位置設置 short 值

下面是用法:

Listing 5.12 get() and set() usage

Charset utf8 = Charset.forName("UTF-8");
ByteBuf buf = Unpooled.copiedBuffer("Netty in Action rocks!", utf8);    //1
System.out.println((char)buf.getByte(0));                    //2

int readerIndex = buf.readerIndex();                        //3
int writerIndex = buf.writerIndex();

buf.setByte(0, (byte)'B');                            //4

System.out.println((char)buf.getByte(0));                    //5
assert readerIndex == buf.readerIndex();                    //6
assert writerIndex ==  buf.writerIndex();

1.創(chuàng)建一個新的 ByteBuf 給指定 String 保存字節(jié)

2.打印的第一個字符,N

3.存儲當前 readerIndex 和 writerIndex

4.更新索引 0 的字符B

5.打印出的第一個字符,現(xiàn)在B

6.這些斷言成功,因為這些操作永遠不會改變索引

現(xiàn)在,讓我們來看看 read() 操作,對當前 readerIndex 或 writerIndex 進行操作。這些用于從 ByteBuf 讀取就好像它是一個流。 (對應的 write() 操作用于“追加”到 ByteBuf?。?。下面展示了常見的  read() 方法。

Table 5.3 read() operations

方法名稱描述
readBoolean()  Reads the Boolean value at the current readerIndex and increases the readerIndex by 1.
readByte() readUnsignedByte() Reads the (unsigned) byte value at the current readerIndex and increases the readerIndex by 1.
readMedium() readUnsignedMedium() Reads the (unsigned) 24-bit medium value at the current readerIndex and increases the readerIndex by 3.
readInt() readUnsignedInt() Reads the (unsigned) int value at the current readerIndex and increases the readerIndex by 4.
readLong() readUnsignedLong()  Reads the (unsigned) int value at the current readerIndex and increases the readerIndex by 8.
readShort() readUnsignedShort() Reads the (unsigned) int value at the current readerIndex and increases the readerIndex by 2.
readBytes(int,int, ...)Reads the value on the current readerIndex for the given length into the given object. Also increases the readerIndex by the length.

每個 read() 方法都對應一個 write()。

Table 5.4 Write operations

方法名稱描述
writeBoolean(boolean) Writes the Boolean value on the current writerIndex and increases the writerIndex by 1.
writeByte(int) Writes the byte value on the current writerIndex and increases the writerIndex by 1.
writeMedium(int) Writes the medium value on the current writerIndex and increases the writerIndex by 3.
writeInt(int) Writes the int value on the current writerIndex and increases the writerIndex by 4.
writeLong(long) Writes the long value on the current writerIndex and increases the writerIndex by 8.
writeShort(int) Writes the short value on the current writerIndex and increases thewriterIndex by 2.
writeBytes(int,...) Transfers the bytes on the current writerIndex from given resources.

Listing 5.13 read()/write() operations on the ByteBuf

Charset utf8 = Charset.forName("UTF-8");
ByteBuf buf = Unpooled.copiedBuffer("Netty in Action rocks!", utf8);    //1
System.out.println((char)buf.readByte());                    //2

int readerIndex = buf.readerIndex();                        //3
int writerIndex = buf.writerIndex();                        //4

buf.writeByte((byte)'?');                            //5

assert readerIndex == buf.readerIndex();
assert writerIndex != buf.writerIndex();

1.創(chuàng)建一個新的 ByteBuf 保存給定 String 的字節(jié)。

2.打印的第一個字符,N

3.存儲當前的 readerIndex

4.保存當前的 writerIndex

5.更新索引0的字符 B

6.此斷言成功,因為 writeByte() 在 5 移動了 writerIndex

更多操作

Table 5.5 Other useful operations

方法名稱描述
isReadable()Returns true if at least one byte can be read.
isWritable()Returns true if at least one byte can be written.
readableBytes()Returns the number of bytes that can be read.
writablesBytes()Returns the number of bytes that can be written.
capacity()Returns the number of bytes that the ByteBuf can hold. After this it will try to expand again until maxCapacity() is reached.
maxCapacity()Returns the maximum number of bytes the ByteBuf can hold.
hasArray()Returns true if the ByteBuf is backed by a byte array.
array()Returns the byte array if the ByteBuf is backed by a byte array, otherwise throws an

UnsupportedOperationException.


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號