<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                除了基本的讀寫操作, ByteBuf 還提供了它所包含的數據的修改方法。 ### [](https://github.com/waylau/essential-netty-in-action/blob/master/CORE%20FUNCTIONS/Byte-level%20Operations.md#隨機訪問索引)隨機訪問索引 ByteBuf 使用zero-based 的 indexing(從0開始的索引),第一個字節的索引是 0,最后一個字節的索引是 ByteBuf 的 capacity - 1,下面代碼是遍歷 ByteBuf 的所有字節: 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 [![](https://box.kancloud.cn/2015-08-18_55d31aa3e1f9e.jpg)](https://github.com/waylau/essential-netty-in-action/blob/master/images/Figure%205.3%20ByteBuf%20internal%20segmentation.jpg) 1.字節,可以被丟棄,因為它們已經被讀 2.還沒有被讀的字節是:“readable bytes(可讀字節)” 3.空間可加入多個字節的是:“writeable bytes(寫字節)” ### [](https://github.com/waylau/essential-netty-in-action/blob/master/CORE%20FUNCTIONS/Byte-level%20Operations.md#可丟棄字節的字節)可丟棄字節的字節 標有“可丟棄字節”的段包含已經被讀取的字節。他們可以被丟棄,通過調用discardReadBytes() 來回收空間。這個段的初始大小存儲在readerIndex,為 0,當“read”操作被執行時遞增(“get”操作不會移動 readerIndex)。 圖5.4示出了在 圖5.3 中的緩沖區中調用 discardReadBytes() 所示的結果。你可以看到,在丟棄字節段的空間已變得可用寫。需要注意的是不能保證對可寫的段之后的內容在 discardReadBytes() 方法之后已經被調用。 Figure 5.4 ByteBuf after discarding read bytes. [![](https://box.kancloud.cn/2015-08-18_55d31aa69fbfc.jpg)](https://github.com/waylau/essential-netty-in-action/blob/master/images/Figure%205.4%20ByteBuf%20after%20discarding%20read%20bytes.jpg) 1.字節尚未被讀出(readerIndex 現在 0)。 2.可用的空間,由于空間被回收而增大。 ByteBuf.discardReadBytes() 可以用來清空 ByteBuf 中已讀取的數據,從而使 ByteBuf 有多余的空間容納新的數據,但是discardReadBytes() 可能會涉及內存復制,因為它需要移動 ByteBuf 中可讀的字節到開始位置,這樣的操作會影響性能,一般在需要馬上釋放內存的時候使用收益會比較大。 ### [](https://github.com/waylau/essential-netty-in-action/blob/master/CORE%20FUNCTIONS/Byte-level%20Operations.md#可讀字節)可讀字節 ByteBuf 的“可讀字節”分段存儲的是實際數據。新分配,包裝,或復制的緩沖區的 readerIndex 的默認值為 0 。任何操作,其名稱以 "read" 或 "skip" 開頭的都將檢索或跳過該數據在當前 readerIndex ,并且通過讀取的字節數來遞增。 如果所謂的讀操作是一個指定 ByteBuf 參數作為寫入的對象,并且沒有一個目標索引參數,目標緩沖區的 writerIndex 也會增加了。例如: ~~~ readBytes(ByteBuf dest); ~~~ 如果試圖從緩沖器讀取已經用盡的可讀的字節,則拋出IndexOutOfBoundsException。清單5.8顯示了如何讀取所有可讀字節。 Listing 5.7 Read all data ~~~ //遍歷緩沖區的可讀字節 ByteBuf buffer= ...; while (buffer.isReadable()) { System.out.println(buffer.readByte()); } ~~~ 這段是未定義內容的地方,準備好寫。一個新分配的緩沖區的 writerIndex 的默認值是 0 。任何操作,其名稱 "write"開頭的操作在當前的 writerIndex 寫入數據時,遞增字節寫入的數量。如果寫操作的目標也是 ByteBuf ,且未指定源索引,則源緩沖區的 readerIndex 將增加相同的量。例如: ~~~ writeBytes(ByteBuf dest); ~~~ 如果試圖寫入超出目標的容量,則拋出 IndexOutOfBoundException。 下面的例子展示了填充隨機整數到緩沖區中,直到耗盡空間。該方法writableBytes() 被用在這里確定是否存在足夠的緩沖空間。 Listing 5.8 Write data ~~~ //填充隨機整數到緩沖區中 ByteBuf buffer = ...; while (buffer.writableBytes() >= 4) { buffer.writeInt(random.nextInt()); } ~~~ ### [](https://github.com/waylau/essential-netty-in-action/blob/master/CORE%20FUNCTIONS/Byte-level%20Operations.md#索引管理)索引管理 在 JDK 的 InputStream 定義了 mark(int readlimit) 和 reset()方法。這些是分別用來標記流中的當前位置和復位流到該位置。 同樣,您可以設置和重新定位ByteBuf readerIndex 和 writerIndex 通過調用 markReaderIndex(), markWriterIndex(), resetReaderIndex() 和 resetWriterIndex()。這些類似于InputStream 的調用,所不同的是,沒有 readlimit 參數來指定當標志變為無效。 您也可以通過調用 readerIndex(int) 或 writerIndex(int) 將指標移動到指定的位置。在嘗試任何無效位置上設置一個索引將導致 IndexOutOfBoundsException 異常。 調用 clear() 可以同時設置 readerIndex 和 writerIndex 為 0。注意,這不會清除內存中的內容。讓我們看看它是如何工作的。 (圖5.5圖重復5.3 ) Figure 5.5 Before clear() is called [![](https://box.kancloud.cn/2015-08-18_55d31aaa09975.jpg)](https://github.com/waylau/essential-netty-in-action/blob/master/images/Figure%205.5%20Before%20clear%20is%20called.jpg) 調用之前,包含3個段,下面顯示了調用之后 Figure 5.6 After clear() is called [![](https://box.kancloud.cn/2015-08-18_55d31aac5c347.jpg)](https://github.com/waylau/essential-netty-in-action/blob/master/images/Figure%205.6%20After%20clear%20is%20called.jpg) 現在 整個 ByteBuf 空間都是可寫的了。 clear() 比 discardReadBytes() 更低成本,因為他只是重置了索引,而沒有內存拷貝。 ### [](https://github.com/waylau/essential-netty-in-action/blob/master/CORE%20FUNCTIONS/Byte-level%20Operations.md#查詢操作)查詢操作 有幾種方法,以確定在所述緩沖器中的指定值的索引。最簡單的是使用 indexOf() 方法。更復雜的搜索執行以 ByteBufProcessor 為參數的方法。這個接口定義了一個方法,boolean process(byte value),它用來報告輸入值是否是一個正在尋求的值。 ByteBufProcessor 定義了很多方便實現共同目標值。例如,假設您的應用程序需要集成所謂的“[Flash sockets](http://help.adobe.com/en_US/as3/dev/WSb2ba3b1aad8a27b0-181c51321220efd9d1c-8000.html)”,將使用 NULL 結尾的內容。調用 ~~~ forEachByte(ByteBufProcessor.FIND_NUL) ~~~ 通過減少的,因為少量的 “邊界檢查”的處理過程中執行了,從而使 消耗 Flash 數據變得 編碼工作量更少、效率更高。 下面例子展示了尋找一個回車符,`\ r`的一個例子。 Listing 5.9 Using ByteBufProcessor to find?`\r` ~~~ ByteBuf buffer = ...; int index = buffer.forEachByte(ByteBufProcessor.FIND_CR); ~~~ ### [](https://github.com/waylau/essential-netty-in-action/blob/master/CORE%20FUNCTIONS/Byte-level%20Operations.md#衍生的緩沖區)衍生的緩沖區 “衍生的緩沖區”是代表一個專門的展示 ByteBuf 內容的“視圖”。這種視圖是由 duplicate(), slice(), slice(int, int),readOnly(), 和 order(ByteOrder) 方法創建的。所有這些都返回一個新的 ByteBuf 實例包括它自己的 reader, writer 和標記索引。然而,內部數據存儲共享就像在一個 NIO 的 ByteBuffer。這使得衍生的緩沖區創建、修改其 內容,以及修改其“源”實例更廉價。 *ByteBuf 拷貝* *如果需要已有的緩沖區的全新副本,使用 copy() 或者 copy(int, int)。不同于派生緩沖區,這個調用返回的 ByteBuf 有數據的獨立副本。* 若需要操作某段數據,使用 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.創建一個 ByteBuf 保存特定字節串。 2.創建從索引 0 開始,并在 14 結束的 ByteBuf 的新 slice。 3.打印 Netty in Action 4.更新索引 0 的字節。 5.斷言成功,因為數據是共享的,并以一個地方所做的修改將在其他地方可見。 下面看下如何將一個 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.創建一個 ByteBuf 保存特定字節串。 2.創建從索引0開始和 14 結束 的 ByteBuf 的段的拷貝。 3.打印 Netty in Action 4.更新索引 0 的字節。 5.斷言成功,因為數據不是共享的,并以一個地方所做的修改將不影響其他。 代碼幾乎是相同的,但所 衍生的 ByteBuf 效果是不同的。因此,使用一個 slice 可以盡可能避免復制內存。 ### [](https://github.com/waylau/essential-netty-in-action/blob/master/CORE%20FUNCTIONS/Byte-level%20Operations.md#讀寫操作)讀/寫操作 讀/寫操作主要由2類: * gget()/set() 操作從給定的索引開始,保持不變 * read()/write() 操作從給定的索引開始,與字節訪問的數量來適用,遞增當前的寫索引或讀索引 ByteBuf 的各種讀寫方法或其他一些檢查方法可以看 ByteBuf 的 API,下面是常見的 get() 操作: Table 5.1 get() operations | 方法名稱 | 描述 | | --- | --- | | getBoolean(int) | 返回當前索引的 Boolean 值 | | getByte(int) getUnsignedByte(int) | 返回當前索引的(無符號)字節 | | getMedium(int) getUnsignedMedium(int) | 返回當前索引的 (無符號) 24-bit 中間值 | | getInt(int) getUnsignedInt(int) | 返回當前索引的(無符號) 整型 | | getLong(int) getUnsignedLong(int) | 返回當前索引的 (無符號) Long 型 | | getShort(int) getUnsignedShort(int) | 返回當前索引的 (無符號) Short 型 | | getBytes(int, ...) | 字節 | 常見 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.創建一個新的 ByteBuf 給指定 String 保存字節 2.打印的第一個字符,`N` 3.存儲當前 readerIndex 和 writerIndex 4.更新索引 0 的字符`B` 5.打印出的第一個字符,現在`B` 6.這些斷言成功,因為這些操作永遠不會改變索引 現在,讓我們來看看 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.創建一個新的 ByteBuf 保存給定 String 的字節。 2.打印的第一個字符,`N` 3.存儲當前的 readerIndex 4.保存當前的 writerIndex 5.更新索引0的字符?`B` 6.此斷言成功,因為 writeByte() 在 5 移動了 writerIndex ### [](https://github.com/waylau/essential-netty-in-action/blob/master/CORE%20FUNCTIONS/Byte-level%20Operations.md#更多操作)更多操作 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.
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看