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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

android 解决java.nio.BufferOverflowException 异常

發(fā)布時(shí)間:2024/4/15 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android 解决java.nio.BufferOverflowException 异常 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個(gè)參考.


昨天,測試程序時(shí),發(fā)現(xiàn)程序了java.nio.BufferOverflowException 異常,后來,在網(wǎng)上搜索了資料,終于解決了問題。這里記錄一下。


ByteBuffer params = ByteBuffer.allocate(2);// 這里只分配了2個(gè)字節(jié),下面的params.put(tmp);卻put了3個(gè)字節(jié)的數(shù)據(jù)。所以導(dǎo)致 java.nio.BufferOverflowException 異常params.order(ByteOrder.LITTLE_ENDIAN); byte[] tmp = new byte[3];tmp[0] = (byte) data1;tmp[1] = (byte) data2;tmp[2] = (byte) data3;params.put(tmp);


錯誤原因:寫入的長度超出了允許的長度:

如何解決這個(gè)問題呢?

添加寫入長度與 ByteBuffer 中可寫入的長度的判斷,例如:

while (writeBuffer.remaining() > 0) {writeBuffer.put((byte)0);}


注意:你每次只寫入一個(gè)字節(jié),那就判斷大于0就好了,如果不是一個(gè)記得修改條件哦!

總結(jié)

當(dāng) ByteBuffer.remaining()??小于要讀取或?qū)懭氲拈L度時(shí),再執(zhí)行讀取或?qū)懭氩僮鞫紩a(chǎn)生異常;

讀取則產(chǎn)生?java.nio.BufferUnderflowException?異常,

寫入則產(chǎn)生?java.nio.BufferOverflowException?異常。

當(dāng)?ByteBuffer.remaining()??等于 0 時(shí),不能再執(zhí)行讀取或?qū)懭氩僮?#xff0c;需要執(zhí)行:clear() 操作,否則將產(chǎn)生異常。


這里介紹一下幾個(gè)Buffer的函數(shù)

1、存取(Buffer.get() & Buffer.put())

使用get()從緩沖區(qū)中取數(shù)據(jù),使用put()向緩沖區(qū)中存數(shù)據(jù)。

// 創(chuàng)建一個(gè)容量為10的byte數(shù)據(jù)緩沖區(qū)ByteBuffer buff = ByteBuffer.allocate(10);// 存入4次數(shù)據(jù)buff.put((byte) 'A');buff.put((byte) 'B');buff.put((byte) 'C');buff.put((byte) 'D');// 翻轉(zhuǎn)緩沖區(qū)buff.flip();// 讀取2次數(shù)據(jù)System.out.println((char)buff.get());System.out.println((char)buff.get());


? 上面有提過緩沖區(qū)四個(gè)屬性值一定遵循capacity>=limit>=position>=mark>=0,put()時(shí),若position超過limit則會拋出BufferOverflowException;get()時(shí),若position超過limit則會拋出BufferUnderflowException。

??????? buff.flip()是將緩沖區(qū)翻轉(zhuǎn),翻轉(zhuǎn)將在下面來說。

調(diào)用put()或get()時(shí),每調(diào)用一次position的值會加1,指示下次存或取開始的位置;


再向Buffer中讀寫數(shù)據(jù)時(shí)有2個(gè)方法也非常有用:

Buffer.remaining():返回從當(dāng)前位置到上界的數(shù)據(jù)元素?cái)?shù)量;

Buffer.hasRemaining():告訴我們從當(dāng)前位置到上界是否有數(shù)據(jù)元素;


2、翻轉(zhuǎn)(Buffer.flip())

??????? 翻轉(zhuǎn)就是將一個(gè)處于存數(shù)據(jù)狀態(tài)的緩沖區(qū)變?yōu)橐粋€(gè)處于準(zhǔn)備取數(shù)據(jù)的狀態(tài),使用flip()方式實(shí)現(xiàn)翻轉(zhuǎn)。Buffer.flip()的源碼如下:

public final Buffer flip() {limit = position;position = 0;mark = -1;return this;}


相信看到了實(shí)現(xiàn)的源碼應(yīng)該就會清楚flip()的作用了。rewind()方法與flip()很相似,區(qū)別在于rewind()不會影響limit,而flip()會重設(shè)limit屬性值,Buffer.rewind()的源碼如下:

public final Buffer rewind() {position = 0;mark = -1;return this;}


3、壓縮(Buffer.compact())

??????? 壓縮就是將已讀取了的數(shù)據(jù)丟棄,保留未讀取的數(shù)據(jù)并將保留的數(shù)據(jù)重新填充到緩沖區(qū)的頂部,然后繼續(xù)向緩沖區(qū)寫入數(shù)據(jù)。

// 創(chuàng)建一個(gè)容量為10的byte數(shù)據(jù)緩沖區(qū)ByteBuffer buff = ByteBuffer.allocate(10);// 填充緩沖區(qū)buff.put((byte)'A');buff.put((byte)'B');buff.put((byte)'C');buff.put((byte)'D');System.out.println("first put : " + new String(buff.array()));//翻轉(zhuǎn)buff.flip();//釋放System.out.println((char)buff.get());System.out.println((char)buff.get());//壓縮buff.compact();System.out.println("compact after get : " + new String(buff.array()));//繼續(xù)填充buff.put((byte)'E');buff.put((byte)'F');//輸出所有System.out.println("put after compact : " + new String(buff.array()));


以上代碼打印結(jié)果:

first put : ABCD

A

B

compact after get : CDCD

put after compact : CDEF

控制臺中輸出內(nèi)容中有正方形的亂碼,是正常。因?yàn)樽止?jié)緩沖區(qū)中沒有賦值的內(nèi)存塊默認(rèn)值是0,而Unicode編碼中沒有0編碼,所以亂碼。


這里簡單這里一下:

方法描述
limit(), limit(10)等其中讀取和設(shè)置這4個(gè)屬性的方法的命名和jQuery中的val(),val(10)類似,一個(gè)負(fù)責(zé)get,一個(gè)負(fù)責(zé)set
reset()把position設(shè)置成mark的值,相當(dāng)于之前做過一個(gè)標(biāo)記,現(xiàn)在要退回到之前標(biāo)記的地方
clear()position = 0;limit = capacity;mark = -1; 有點(diǎn)初始化的味道,但是并不影響底層byte數(shù)組的內(nèi)容
flip()limit = position;position = 0;mark = -1; 翻轉(zhuǎn),也就是讓flip之后的position到limit這塊區(qū)域變成之前的0到position這塊,翻轉(zhuǎn)就是將一個(gè)處于存數(shù)據(jù)狀態(tài)的緩沖區(qū)變?yōu)橐粋€(gè)處于準(zhǔn)備取數(shù)據(jù)的狀態(tài)
rewind()把position設(shè)為0,mark設(shè)為-1,不改變limit的值
remaining()return limit - position; 返回limit和position之間相對位置差
hasRemaining()return position < limit返回是否還有未讀內(nèi)容
compact()把從position到limit中的內(nèi)容移到0到limit-position的區(qū)域內(nèi),position和limit的取值也分別變成limit-position、capacity。如果先將positon設(shè)置到limit,再compact,那么相當(dāng)于clear()
get()相對讀,從position位置讀取一個(gè)byte,并將position+1,為下次讀寫作準(zhǔn)備
get(int index) 絕對讀,讀取byteBuffer底層的bytes中下標(biāo)為index的byte,不改變position
get(byte[] dst, int offset, int length)從position位置開始相對讀,讀length個(gè)byte,并寫入dst下標(biāo)從offset到offset+length的區(qū)域
put(byte b)相對寫,向position的位置寫入一個(gè)byte,并將postion+1,為下次讀寫作準(zhǔn)備
put(int index, byte b)絕對寫,向byteBuffer底層的bytes中下標(biāo)為index的位置插入byte b,不改變position
put(ByteBuffer src)用相對寫,把src中可讀的部分(也就是position到limit)寫入此byteBuffer
put(byte[] src, int offset, int length)從src數(shù)組中的offset到offset+length區(qū)域讀取數(shù)據(jù)并使用相對寫寫入此byteBuffer


















以下為一些測試方法:如果需要存入一個(gè)byte數(shù)組,buffer.put(Byte[] b)和put(b,? 0,? b.length)是一樣的。


android 解決java.nio.BufferOverflowException 異常就講完了。


就這么簡單。


總結(jié)

以上是生活随笔為你收集整理的android 解决java.nio.BufferOverflowException 异常的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。