java bytebuffer是什么,讓我們一起了解一下?
bytebuffer是buffer緩沖區的一種,看作提供了一些(未定義的)底層字節存儲的視圖,需要注意的是幾個操作的影響:flip(),clear(),rewind(),還有就是在讀取或者寫入時,標志的變化。
比如get()方法導致position加1,SocketChannel采用的是非阻塞異步讀取流數據,在讀取的時候,通常是如下代碼示例:
ByteBuffer.clear(); SocketChannel.read(ByteBuffer);
如果流中有數據,就會把數據從position開始讀到ByteBuffer中,在讀取之前ByteBuffer的clear操作會把position置為0,limit置為capability,也就是相當于清空了之前的內容,但是ByteBuffer中數組的內容在read之前是沒有改變的。
read之后,通常就是開始從ByteBuffer中提取讀到的數據,如果你的數據是以自己定義的數據包的格式進行發送的,那你還需要判斷是否讀到了數據包的結尾,因為對流數據本身來說是沒有結尾這一說的。在提取數據之前,要先把position放到開始讀取時的位置,把limit放到當前位置,所以要flip一下,表示從position到limit的位置都是需要的數據。
這樣以來也存在一個問題,當一次讀到的ByteBuffer不包含完整的數據包或者包含多個數據包,那么就需要在下一次繼續把這些包分拆出來。
另外一個可能會用到的操作就是ByteBuffer.rewind(),他會把position置為0,limit保持不變,可以用于重復讀取一段數據。
實戰操作:
ByteBuffer類提供了4個靜態工廠方法來獲得ByteBuffer的實例:
1、allocate(int capacity):從堆空間中分配一個容量大小為capacity的byte數組作為緩沖區的byte數據存儲器。
2、allocateDirect(int capacity):是不使用JVM堆棧而是通過操作系統來創建內存塊用作緩沖區,它與當前操作系統能夠更好的耦合,因此能進一步提高I/O操作速度。但是分配直接緩沖區的系統開銷很大,因此只有在緩沖區較大并長期存在,或者需要經常重用時,才使用這種緩沖區。
3、wrap(byte[] array):這個緩沖區的數據會存放在byte數組中,bytes數組或buff緩沖區任何一方中數據的改動都會影響另一方。其實ByteBuffer底層本來就有一個bytes數組負責來保存buffer緩沖區中的數據,通過allocate方法系統會幫你構造一個byte數組。
4、wrap(byte[] array,int offset, int length):在上一個方法的基礎上可以指定偏移量和長度,這個offset也就是包裝后byteBuffer的position,而length呢就是limit-position的大小,從而我們可以得到limit的位置為length+position(offset)。
測試方法:
public?static?void?main(String?args[])?throws?FileNotFoundException?{?? ?? ????System.out.println("----------Test?allocate--------");?? ????System.out.println("before?alocate:"?? ????????????+?Runtime.getRuntime().freeMemory());?? ?????? ????//?如果分配的內存過小,調用Runtime.getRuntime().freeMemory()大小不會變化??? ????//?要超過多少內存大小JVM才能感覺到??? ????ByteBuffer?buffer?=?ByteBuffer.allocate(102400);?? ????System.out.println("buffer?=?"?+?buffer);?? ?????? ????System.out.println("after?alocate:"?? ????????????+?Runtime.getRuntime().freeMemory());?? ?????? ????//?這部分直接用的系統內存,所以對JVM的內存沒有影響?? ????ByteBuffer?directBuffer?=?ByteBuffer.allocateDirect(102400);?? ????System.out.println("directBuffer?=?"?+?directBuffer);?? ????System.out.println("after?direct?alocate:"?? ????????????+?Runtime.getRuntime().freeMemory());?? ?????? ????System.out.println("----------Test?wrap--------");?? ????byte[]?bytes?=?new?byte[32];?? ????buffer?=?ByteBuffer.wrap(bytes);?? ????System.out.println(buffer);?? ?????? ????buffer?=?ByteBuffer.wrap(bytes,?10,?10);?? ????System.out.println(buffer);??? }
以上就是小編今天的分享了,希望可以幫助到大家。