mappedbytebuffer_Java NIO Buffer【MappedByteBuffer】概述与FileChannel的联系
生活随笔
收集整理的這篇文章主要介紹了
mappedbytebuffer_Java NIO Buffer【MappedByteBuffer】概述与FileChannel的联系
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
“?NIO【Non-blocking IO非阻塞式IO】,可以讓你非阻塞的使用IO,例如:當線程從通道讀取數據到緩沖區時,線程還是可以進行其他事情。當數據被寫入到緩沖區時,線程可以繼續處理它。從緩沖區寫入通道也類似,主要分為3部分:Channels and Buffers and Selectors(通道和緩沖區和選擇器)今天我們要講的就是Buffer概述”
聽歌時間
01
—
Buffer概述
/**?* Java NIO中的Buffer用于和NIO通道{Channel【FileChannel|SocketChannel】}進行交互,
?* 數據是從通道讀入緩沖區,從緩沖區寫入到通道中的。
?* 緩沖區本質上是一塊可以寫入數據,然后可以從中讀取數據的內存。
?* 這塊內存被包裝成NIO Buffer對象,并提供了一組方法,用來方便的訪問該塊內存。
?* 用于特定基本類型的數據的緩沖區容器,每個非布爾基本類型都有這個類的一個子類
?* ByteBuffer , CharBuffer , DoubleBuffer , FloatBuffer , IntBuffer , LongBuffer , ShortBuffer
?* 其中和ByteBuffer相關的子類有3個:
?* MappedByteBuffer,HeapByteBuffer,DirectByteBuffer extends MappedByteBuffer
?* 是特定原始類型的元素的線性有限序列緩沖區。除了其內容【緩沖區數組】,
?* 緩沖區對象還有其它3個基本屬性
?* 1:capacity:它所包含的元素數量叫緩沖區的容量。緩沖區的容量永遠不會為負且永遠不會改變
?* 2:limit:第一個不能被讀/寫的元素的索引叫緩沖區的限制。緩沖區的限制永遠不大于緩沖區的容量
?* 3:position:下一個要讀取或寫入的元素的索引叫緩沖區的位置。緩沖區的位置永遠不會大于其限制。
?* Buffer類的每個子類定義了一系列get和put操作:
?* 相對的讀寫操作每次都從當前位置開始讀寫,并將位置+1
?* 絕對的讀寫操作采用顯式的元素索引,并不影響位置
?* 無論是相對的還是絕對的讀寫操作,索引都不能超過【exceeds】其限制
?* 標記,位置,極限和容量值滿足以下關系:
?* 0 <=?mark?<= position?<= limit?<= capacity
?* 標記和重置、清理,翻轉和倒帶
?* 調用reset方法一定保證mark方法被調用過
?* mark方法源碼:
?* mark?= position;return?this;
?* reset方法源碼:
?* int?m?= mark;if?(m?< 0){throw?new?InvalidMarkException()};position?= m;return?this;
?* clear方法源碼:
?* position?= 0;limit?= capacity;mark?= -1;return?this;
?* flip方法源碼:
?* limit?= position;position?= 0;mark?= -1;return?this;
?* rewind方法源碼:
?* position?= 0;mark?= -1;return?this;
?* 讀與寫操作之間要調用flip方法
?* 線程不安全,可以鏈式調用
?* b.flip().position(23).limit(42);
?*
?*/
02
—
代碼演示
import?java.nio.ByteBuffer;import?java.util.Arrays;public?class?ByteBufferTest?{public?static?void?main(String[] args)?{//根據指定的容量創建一個字節緩沖區,兩種方式//分配5個字節????????ByteBuffer byteBuffer = ByteBuffer.allocate(5);//ByteBuffer.wrap(new byte[5]);// 往 ByteBuffer放入數值
????????byteBuffer.put((byte)10);
????????byteBuffer.put((byte)20);//byteBuffer.putInt(1000);//放入一個int占4個字節
????????System.out.printf("打印一下字節數組: %s%n",Arrays.toString(byteBuffer.array()));
????????System.out.printf("打印一下是否有字節數組: %s%n",byteBuffer.hasArray());
????????System.out.printf("打印一下指針位置: %s%n",byteBuffer.position());
????????System.out.printf("打印一下字節緩沖區容量: %s%n",byteBuffer.capacity());
????????System.out.printf("打印一下字節緩沖區限制: %s%n",byteBuffer.limit());
????????System.out.printf("打印一下字節緩沖區從當前位置到限制之間的剩余元素: %s%n",byteBuffer.remaining());
????????System.out.printf("從當前位置到限制之間是否有剩余元素: %s%n",byteBuffer.hasRemaining());
????????System.out.printf("是否是直接緩沖區: %s%n",byteBuffer.isDirect());
????????System.out.printf("該緩沖區是否是只讀: %s%n",byteBuffer.isReadOnly());//設置位置和限制
????????byteBuffer.flip().position(2).limit(4);
????????System.out.printf("打印一下字節數組: %s%n",Arrays.toString(byteBuffer.array()));//get方法獲取的是position+1的索引對應的值
????????System.out.printf("flip之后獲取位置為2的數據: %s%n",byteBuffer.get());
????????System.out.printf("標記后重置: %s%n",byteBuffer.mark().reset());
????????byteBuffer.put((byte)60);
????????System.out.printf("重新獲取位置: %s%n",byteBuffer.position());//該方法和flip方法差不多,都用于讀寫切換,只不過rewind方法前提是limit被合理的設置
????????byteBuffer.rewind();
????????System.out.printf("重新獲取值: %s%n",byteBuffer.get());//重置為最開始創建的時候,只不過沒有清除數據
????????System.out.printf("重置但不清除數據: %s%n",byteBuffer.clear());//創建一個新的剩余內容子共享緩沖區,【也就是說字節數組是共享的】// 該新的緩沖區是指定緩沖區的剩余部分,修改哪一個另外一個都會同步修改//這兩個緩沖區的位置,限制和標記值將是獨立的//通過position++加上offset來定位在原數組中的位置
????????ByteBuffer subByteBuffer = byteBuffer.slice();
????????subByteBuffer.put((byte)30);
????????System.out.printf("打印一下子字節數組: %s%n",Arrays.toString(subByteBuffer.array()));//只有調用slice方法,offset才會被設置
????????System.out.printf("打印一下緩沖區偏移量: %s%n",subByteBuffer.arrayOffset());
????????System.out.printf("打印一下子指針位置: %s%n",subByteBuffer.position());
????????System.out.printf("打印一下子字節緩沖區容量: %s%n",subByteBuffer.capacity());
????????System.err.printf("打印一下字節數組: %s%n",Arrays.toString(byteBuffer.array()));
????????System.err.printf("打印一下指針位置: %s%n",byteBuffer.position());
????????System.err.printf("打印一下字節緩沖區容量: %s%n",byteBuffer.capacity());
????????System.err.printf("打印一下字節緩沖區限制: %s%n",byteBuffer.limit());
????????byteBuffer.rewind();
????????System.err.printf("獲取: %s%n",byteBuffer.get());
????}
}
03
—
MappedByteBuffer概述與聯系
直接字節緩沖器,其內容是文件的存儲器映射區域。映射的字節緩沖區是通過FileChannel.map方法創建的。此類擴展了具有特定于內存映射文件區域的操作的ByteBuffer類。
映射字節緩沖區及其表示的文件映射在緩沖區本身被垃圾回收之前保持有效。
映射字節緩沖區的內容可以隨時更改,例如,如果該程序或其他映射文件的對應區域的內容被更改。
這種變化是否發生,何時發生,是操作系統依賴的,因此是未指定的。
映射字節緩沖區的全部或部分可能在任何時候變得無法訪問,例如映射文件被截斷。
訪問映射字節緩沖區的不可訪問區域的嘗試不會更改緩沖區的內容,
并將導致在訪問時或稍后的時候拋出未指定的異常。因此,強烈建議您采取適當的預防措施,
以避免該程序或同時運行的程序對映射文件進行操作,但讀取或寫入文件的內容除外。
映射的字節緩沖區的行為與普通的直接字節緩沖區不同。
04
—
FileChannel
寫在最后
總結:今天花了點時間寫了關于Buffer的概述,關于實戰部分請參考往期精彩文章>>>往期精彩文章
使用一種全新的方式【java NIO】拆分大電影文件,并合并分割后的文
件為電影文件
如果喜歡,歡迎點贊分享給你身邊需要的人!
我欲尋花問路,直入白云深處。
總結
以上是生活随笔為你收集整理的mappedbytebuffer_Java NIO Buffer【MappedByteBuffer】概述与FileChannel的联系的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎么压缩图片大小苹果手机怎么压缩图片大小
- 下一篇: 纽曼手机是华为旗下的吗(纽曼属于华为吗)