【Netty】NIO 缓冲区 ( Buffer ) ( 缓冲区读写类型 | 只读缓冲区 | 映射字节缓冲区 )
文章目錄
- I . 緩沖區(qū) ( Buffer ) 存取類型
- II . 只讀緩沖區(qū) ( ReadOnlyBuffer )
- III . 映射字節(jié)緩沖區(qū) ( MappedByteBuffer )
I . 緩沖區(qū) ( Buffer ) 存取類型
1 . 緩沖區(qū) ( Buffer ) 數(shù)據(jù)讀寫類型 注意點(diǎn) : 以 字節(jié)緩沖區(qū) ( ByteBuffer ) 為例 ;
① 向 字節(jié)緩沖區(qū) ( ByteBuffer ) 中放入數(shù)據(jù) :
- 放入 Int 類型數(shù)據(jù) : ByteBuffer putInt(int value) ;
- 放入 Double 類型數(shù)據(jù) : ByteBuffer putDouble(double value) ;
- 放入 Short 類型數(shù)據(jù) : ByteBuffer putShort(short value) ;
② 從 字節(jié)緩沖區(qū) ( ByteBuffer ) 中讀取數(shù)據(jù) :
- 取出 Int 類型數(shù)據(jù) : int getInt() ;
- 取出 Double 類型數(shù)據(jù) : double getDouble() ;
- 取出 Short 類型數(shù)據(jù) : short getShort() ;
③ 讀取數(shù)據(jù)注意點(diǎn) : 讀取 字節(jié)緩沖區(qū) ( ByteBuffer ) 數(shù)據(jù)時(shí) , 必須按照放入 字節(jié)緩沖區(qū) ( ByteBuffer ) 中的數(shù)據(jù)進(jìn)行 , 否則就會(huì)讀出錯(cuò)誤數(shù)據(jù) , 或亂碼 ;
④ 讀取溢出 : 讀取 或 寫出時(shí) , position 一定不能超過 limit , 否則就會(huì)報(bào) BufferUnderFlowException 異常 ;
Exception in thread "main" java.nio.BufferUnderflowExceptionat java.nio.Buffer.nextGetIndex(Buffer.java:506)at java.nio.HeapByteBuffer.getInt(HeapByteBuffer.java:361)at kim.hsl.nio.BufferDemo2.main(BufferDemo2.java:23)代碼示例 :
package kim.hsl.nio;import java.nio.ByteBuffer;public class BufferDemo2 {public static void main(String[] args) {//1 . 創(chuàng)建一個(gè)存儲(chǔ) Int 類型數(shù)據(jù)的 Buffer , 可以存儲(chǔ) 1024 個(gè)字節(jié)ByteBuffer buffer = ByteBuffer.allocate(1024);//2 . 向緩沖區(qū)中放入數(shù)據(jù)buffer.putInt(8888);buffer.putDouble(88.888);buffer.putShort((short) 888);//3 . 寫入轉(zhuǎn)讀取前先翻轉(zhuǎn), 將 position 設(shè)置為 0buffer.flip();//4 . 從緩沖區(qū)中讀取數(shù)據(jù)int intValue = buffer.getInt();double doubleValue = buffer.getDouble();short shortValue = buffer.getShort();//已經(jīng)讀取完了, 在讀取就溢出了 java.nio.BufferUnderflowException//buffer.getInt();//5 . 打印讀取的數(shù)據(jù)信息System.out.println(String.format("intValue = %d, doubleValue = %f, shortValue = %d", intValue, doubleValue, shortValue));} }執(zhí)行結(jié)果 :
intValue = 8888, doubleValue = 88.888000, shortValue = 888II . 只讀緩沖區(qū) ( ReadOnlyBuffer )
1 . 只讀 緩沖區(qū) ( ReadOnlyBuffer ) :
① 只讀緩沖區(qū) ( ReadOnlyBuffer ) 獲取 : 先創(chuàng)建一個(gè) Buffer 對(duì)象 , 向其中存儲(chǔ)數(shù)據(jù) , 調(diào)用 asReadOnlyBuffer() 方法 , 可以返回一個(gè)只讀緩沖區(qū) , 該緩沖區(qū) , 只能讀取 , 不能寫入 ;
② 實(shí)際類型 : 只讀緩沖區(qū)的類型是 HeapByteBufferR ;
③ 只讀緩沖區(qū)寫入數(shù)據(jù)異常 : 該 只讀緩沖區(qū) ( ReadOnlyBuffer ) 只能讀取數(shù)據(jù) , 不能向其中寫入數(shù)據(jù) ; 如果寫入數(shù)據(jù) , 就會(huì)報(bào)異常 ;
Exception in thread "main" java.nio.ReadOnlyBufferExceptionat java.nio.HeapByteBufferR.putShort(HeapByteBufferR.java:324)at kim.hsl.nio.BufferDemo3.main(BufferDemo3.java:28)2 . 示例代碼 :
package kim.hsl.nio;import java.nio.ByteBuffer;public class BufferDemo3 {public static void main(String[] args) {//1 . 創(chuàng)建一個(gè)存儲(chǔ) Int 類型數(shù)據(jù)的 Buffer , 可以存儲(chǔ) 1024 個(gè)字節(jié)ByteBuffer buffer = ByteBuffer.allocate(1024);//2 . 向緩沖區(qū)中放入數(shù)據(jù)buffer.putInt(8888);buffer.putDouble(88.888);buffer.putShort((short) 888);//3 . 寫入轉(zhuǎn)讀取前先翻轉(zhuǎn), 將 position 設(shè)置為 0buffer.flip();//4 . 將上述緩沖區(qū)轉(zhuǎn)為只讀緩沖區(qū)ByteBuffer readOnlyBuffer = buffer.asReadOnlyBuffer();//5 . 從緩沖區(qū)中讀取數(shù)據(jù)int intValue = readOnlyBuffer.getInt();double doubleValue = readOnlyBuffer.getDouble();short shortValue = readOnlyBuffer.getShort();//已經(jīng)讀取完了, 在讀取就溢出了 java.nio.BufferUnderflowException//buffer.getInt();//向只讀緩沖區(qū)中存放數(shù)據(jù)拋 java.nio.ReadOnlyBufferException 異常//readOnlyBuffer.putShort((short) 888);//5 . 打印讀取的數(shù)據(jù)信息System.out.println(String.format("intValue = %d, doubleValue = %f, shortValue = %d",intValue, doubleValue, shortValue));} }執(zhí)行結(jié)果 :
intValue = 8888, doubleValue = 88.888000, shortValue = 888III . 映射字節(jié)緩沖區(qū) ( MappedByteBuffer )
1 . 映射字節(jié)緩沖區(qū) ( MappedByteBuffer ) : 在內(nèi)存中修改文件 , 不需要將文件中的內(nèi)容拷貝到內(nèi)存中 , 再修改后 , 寫回到文件 , 其性能提高了很多 ;
① 內(nèi)存說明 : 修改文件的內(nèi)存并不是堆內(nèi)存 , 而是在堆外內(nèi)存中 ;
② MappedByteBuffer 類結(jié)構(gòu) :
- MappedByteBuffer 繼承 ByteBuffer 抽象類 ;
- MappedByteBuffer 本身也是抽象類 , 其有兩個(gè)子類 , 分別是 DirectByteBuffer , DirectByteBufferR ;
③ 可操作區(qū)域 : fc.map(FileChannel.MapMode.READ_WRITE, 0, 10); 的 MappedByteBuffer 只能操作 從 0 索引開始的 10 個(gè)字節(jié) , 即從 0 到 9 索引代表的字節(jié) , 其中的 10 代表可操作性的字節(jié)個(gè)數(shù) , 并不是索引值 ;
2 . 代碼示例 :
package kim.hsl.nio;import java.io.IOException; import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel;public class MappedByteBufferDemo {public static void main(String[] args) {RandomAccessFile randomAccessFile = null;try {randomAccessFile = new RandomAccessFile("file.txt", "rw");FileChannel fc = randomAccessFile.getChannel();//FileChannel.MapMode.READ_WRITE : 指的是讀寫模式//0 : 將文件從 0 位置開始映射到內(nèi)存中//10 : 將文件從 0 位置開始映射到內(nèi)存中的大小//即 將 file.txt 文件從 0 開始的 10 字節(jié)映射到內(nèi)存中MappedByteBuffer mappedByteBuffer = fc.map(FileChannel.MapMode.READ_WRITE, 0, 10);mappedByteBuffer.put(0, (byte) 'N');mappedByteBuffer.put(1, (byte) 'N');} catch (IOException e) {e.printStackTrace();} finally {try {if(randomAccessFile != null)randomAccessFile.close();} catch (IOException e) {e.printStackTrace();}}} }執(zhí)行結(jié)果 : 在 IntelliJ IDEA 環(huán)境中打開沒有刷新 , 在文件瀏覽器中打開 , “Hello World” 的前兩位變成了 “NN” ;
總結(jié)
以上是生活随笔為你收集整理的【Netty】NIO 缓冲区 ( Buffer ) ( 缓冲区读写类型 | 只读缓冲区 | 映射字节缓冲区 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Netty】NIO 通道 ( Chan
- 下一篇: 【Netty】NIO 缓冲区 ( Buf