日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ByteBuffer详解(大概2333)

發布時間:2024/1/8 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ByteBuffer详解(大概2333) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ByteBuffer詳解

  • ByteBuffer詳解
    • 概述
    • ByteBuffer屬性
      • capacity
      • limit
      • position
      • Mark
    • ByteBuffer方法
      • allocate()
      • order()
      • put()
      • flip()
      • array()
      • get()
      • wrap()
      • clear()
      • rewind()
      • campact()
    • 最后

概述

ByteBuffer顧名思義就是byte緩沖區,實際上底層就是byte[ ]。ByteBuffer有兩種,一種是HeapByteBuffer,還有一種是DirectByteBuffer。我們知道ByteBuffer實際就是一塊內存,前者是屬于JVM的內存,后者則是申請的JVM以外的內存,也就是運行JVM的系統的內存。沒有特殊需求一般都是用HeapByteBuffer吧(大概,畢竟我也沒工作,不知道大佬們的世界)。

ByteBuffer屬性

capacity

容量(capacity),由我們根據需要指定,也就是這個ByteBuffer在內存中分配的(也即是可使用的最大)空間。比如我們new byte[233];這里233就是capacity。類比數組,capacity在指定后不允許改變。capacity()有參則是setter,無參則是getter,下面的limit和position屬性同理。mark則稍有不同。

limit

界限(limit,原諒我不能信達雅),初始化時等于capacity,我們申請了capacity那么大的空間,但是我們未必時時刻刻都有那么大的數據。java就是用limit來界定我們的數據界限在哪,比如limit=10,capacity=20,那么10到20之間就是空閑空間(但是我們也不能直接使用這片空間)。我們所有的讀寫操作都受limit限制,不能操作超過limit的那片空間。如果我們想用上面那片10到20之間的空間,那么我們就要使limit等30。然后我們就能操作30之前的空間。limit最大能等于capacity,因為我們就申請了capacity那么大的空間,如果limit超過capacity那就會操作了不屬于ByteBuffer,跟數組越界一個道理。記住一句話,我們所有的讀寫操作都起于position,終于limit,最大能等于capacity。

position

定位(position),初始化時等于0,指向我們下一個要操作的位置,有點類似PC指針。無論我們是要讀還是寫,操作的都是position指向的位置,操作完position就加一,指向你下一個要操作的位置。position最大能等于limit,此時就不能再操作了,因為你操作完position加一就大于limit了,那就越界了,會報java.nio.BufferOverflowException異常。

Mark

標記(Mark),初始化時等于-1,類似書簽,我們在某時刻調用mark()方法,那么mark將等于position。然后我們想回到我們mark的地方時可以調用reset()方法。網絡用語馬克就是mark音譯。

ByteBuffer方法

allocate()

public static ByteBuffer allocate(int capacity)
Allocates a new byte buffer.
The new buffer’s position will be zero, its limit will be its capacity, its mark will be undefined, and each of its elements will be initialized to zero. It will have a backing array, and its array offset will be zero.

ByteBuffer初始化方法,參數是int,也就capacity。比如ByteBuffer byteBuffer=ByteBuffer.allocate(20);就是為ByteBuffer開辟了一塊20字節大小的內存空間。注意指定capacity后就不能更改了,除非你重新new一個ByteBuffer,不過那就是另外一個ByteBuffer了。

order()

public final ByteBuffer order(ByteOrder bo)
Modifies this buffer’s byte order.
Parameters:
bo - The new byte order, either BIG_ENDIAN or LITTLE_ENDIAN

ByteBuffer是有字節序的,所謂字節序就是把字節放進ByteBuffer的順序。比如我們ByteBuffer的內存地址是0xFFFF 0000到0xFFFF 00FF,我們現在要把一個byte數組放進ByteBuffer,那么我們是從0xFFFF 00FF開始放起,還是從0xFFFF 0000開始放起呢?ByteOrder就是指明我們按照什么順序放的。byte還看不出什么不同,但是當我們讀寫那些不止一個字節的對象時就體現出不同了,比如讀int類型從0xFFFF 0000到0xFFFF 0004跟從0xFFFF 0004到0xFFFF 0000完全就是兩個不同的數。order()有參數就是設置字節序,沒參數就是返回ByteBuffer當前字節序。不過這個感覺一般來說不用管。

put()

public abstract ByteBuffer put(byte b)
Relative put method (optional operation).
Writes the given byte into this buffer at the current position, and then increments the position.

就是把數據放進ByteBuffer的方法,有多種變種,比如put(byte),put(byte[]),put(byte[] src,int offset,int length),put(ByteBuffer src)等等。你寫入多少個字節的數據position就加多少。

flip()

public final Buffer flip()
Flips this buffer. The limit is set to the current position and then the position is set to zero. If the mark is defined then it is discarded.

flip()方法就是把limit設置成當前position,然后position=0,附帶把mark置-1,也就是舍棄你可能有的標記。簡單來說這個方法的作用就是把寫模式變成讀模式。比如你初始化一個ByteBuffer,此時position=0,limit=capacity。然后你向其中寫入了5個字節的數據(假設capacity大于5),此時position=5,limit=capacity。現在你想把寫入的5字節數據讀出來,假如你直接讀,那么你會讀到位與5的數據,然后position=6。這顯然不符合我們的需求。我們需要把position置0,因為我們希望下個操作的數據位于0位置。這樣我們能正確讀出那五個數據了,但是我們沒有設置limit,那么我們完全有可能讀到5以后的數據。這樣也是不行的,那么我們就需要把limit設置成5,也就是寫完后position的位置。這樣我們就只會讀5個字節的數據,覺不會多讀。

array()

public final byte[] array()
Returns the byte array that backs this buffer (optional operation).
Modifications to this buffer’s content will cause the returned array’s content to be modified, and vice versa.
Invoke the hasArray method before invoking this method in order to ensure that this buffer has an accessible backing array.

前面說過ByteBuffer實質就是一個byte[],這個方法就是返回ByteBuffer底層的byte數組,也就是說你對ByteBuffer的所有操作實質就是操作這個byte數組,反之亦然。需要注意的是操作數組不會影響ByteBuffer的position,limit,mark等屬性,同時對數組的操作和一般數組沒有任何區別,不受ByteBuffer那些屬性影響。

get()

public abstract byte get()
Relative get method. Reads the byte at this buffer’s current position, and then increments the position.

用flip()或者手動準備好讀后,可以使用get()方法讀取ByteBuffer的數據,和put()方法一樣get()有很多延伸,可以根據自己需要選取。

wrap()

public static ByteBuffer wrap(byte[] array)
Wraps a byte array into a buffer.
The new buffer will be backed by the given byte array; that is, modifications to the buffer will cause the array to be modified and vice versa. The new buffer’s capacity and limit will be array.length, its position will be zero, and its mark will be undefined. Its backing array will be the given array, and its array offset> will be zero.

文檔說的很清楚了,就是以你給定的字節數組為底層數組構建一個ByteBuffer。

//wrap()創建ByteBuffer byte[] array=new byte[233]; ByteBuffer byteBuffer=ByteBuffer.wrap(array);//allocate創建ByteBuffer ByteBuffer byteBuffer=ByteBuffer.allocate(233); byte[] array=byteBuffer.array();

上面兩種創建ByteBuffer的方式,前者不會開辟新的內存空間,而是直接使用array的內存空間,同時保留array數組原有數據。而后者會開辟新的內存空間。

clear()

public final Buffer clear()
Clears this buffer. The position is set to zero, the limit is set to the capacity, and the mark is discarded.

clear()做的就是把position=0,limit=capacity,mark=-1,clear()只是移動指針,不改變ByteBuffer里面的數據。此時如果你要寫,那么ByteBuffer就相當于空的,如果你要讀,那么ByteBuffer就相當于寫滿數據的。

rewind()

public final Buffer rewind()
Rewinds this buffer. The position is set to zero and the mark is discarded.

如上,position=0,mark被舍棄,也就是說你讀寫到一半或讀寫完了,現在想從頭開始,那就調用rewind()方法,從頭開始。

campact()

public abstract ByteBuffer compact()
Compacts this buffer (optional operation).
The bytes between the buffer’s current position and its limit, if any, are copied to the beginning of the buffer. That is, the byte at index p = position() is copied to index zero, the byte at index p + 1 is copied to index one, and so forth until the byte at index limit() - 1 is copied to index n = limit() - 1 - p. The buffer’s position is then set to n+1 and its limit is set to its capacity. The mark, if defined, is discarded.
The buffer’s position is set to the number of bytes copied, rather than to zero, so that an invocation of this method can be followed immediately by an invocation of another relative put method.

如上所說,調用campact()方法會把position和limit之間的數據移動到ByteBuffer開始的地方,然后position=limit-position,也就是position接在被轉移的數據后面,然后limit=capacity。這個方法的作用是把我們未讀完的數據放到前面,以便我們接著后面寫入數據,因為我們不能期望一次把所有數據讀完。總會出現在還未讀完數據的時候需要寫入數據的情況,此時如果你不需要未讀的那些數據,可以clear(),如果需要保留那些數據則campact()。

最后

其實寫博客很難受,要考慮寫得對寫得全,又要通俗易懂,寫到最后我都有點偷工減料了,如果有哪里不清楚,自己寫段簡單代碼驗證一下就是了,更多ByteBuffer特性用法請參閱官方API文檔。同時如果有哪里寫錯了還請不吝賜教。最后祝各位能找到自己的真物。

總結

以上是生活随笔為你收集整理的ByteBuffer详解(大概2333)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产大片一区二区 | 精品人妻无码一区二区三区蜜桃一 | 天堂…中文在线最新版在线 | 99re在线视频免费观看 | 91久久一区二区三区 | 天堂中文在线资 | 亚洲av无码一区二区三区四区 | 欧美做爰全过程免费看 | 岛国一区二区三区 | 久热精品视频在线观看 | 后宫秀女调教(高h,np) | 欧美性做爰猛烈叫床潮 | 哈利波特3在线观看免费版英文版 | 九九久久精品 | 亚洲综合日韩精品欧美综合区 | 欧美在线xxxx | 日韩av片免费观看 | 黄色片亚洲 | 日韩视频中文字幕 | 日韩中文字幕第一页 | 91国产丝袜播放在线 | 日韩美女av在线 | 制服丝袜第一页在线观看 | 影音先锋国产在线 | 亚洲精品国产成人av在线 | 国产精品久久久久久69 | 色久天堂 | 国产伦精品一区二区三区照片91 | 日韩av一二三区 | 国产精品va在线观看无码 | 国产毛片欧美毛片久久久 | 爽爽爽av | 欧美精品久久久久久久多人混战 | 天天色影网 | 91香蕉视频在线看 | 久久综合五月天 | 美女被c出水 | 久久久夜 | 亚洲8888| 欧美xxxx888| 一区二区三区av在线 | 久久字幕| 国产成人在线观看免费网站 | 久久久久中文字幕亚洲精品 | 成人午夜精品一区二区 | 免费特级黄色片 | 二男一女一级一片 | 性活交片大全免费看 | 日本激情久久 | 久久精品99久久久久久久久 | 夜色一区二区三区 | 欧美一级片网址 | a一级免费视频 | 亚洲永久免费观看 | 老司机成人免费视频 | 亚洲成人自拍网 | 日本簧片在线观看 | 黄色爱爱视频 | 亚洲插插插 | av黄页| 极品女神无套呻吟啪啪 | 久久五月婷 | 亚洲一区二区91 | 老头老太吃奶xb视频 | xx久久 | 丁香婷婷综合网 | 老司机免费精品视频 | 国产精品美女www爽爽爽视频 | 欧美 日韩 国产 成人 在线 | 黄色片网站大全 | 91香蕉国产在线观看软件 | 亚洲成人第一区 | 日韩伊人久久 | 亚洲成人激情视频 | 天天在线观看 | 最色网站 | 国产香蕉尹人视频在线 | 深爱综合网 | 欧美性受xxxx狂喷水 | 中文字幕一区二区三区乱码在线 | 国产二级视频 | 欧美一区二区三区的 | 久草免费av| 男人的天堂你懂的 | 亚洲网址在线观看 | 日韩不卡视频在线观看 | 国产精品美女网站 | 五月深爱网 | 日日射夜夜操 | 自拍偷拍18p| 免费久草视频 | 欧美成人精品在线 | 播播网色播播 | 伊人春色在线 | 亚洲人掀裙打屁股网站 | 天天干天天做 | 久草aⅴ| 玖玖爱av | 国产激情综合五月久久 |