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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

android 解决java.nio.BufferOverflowException 异常

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


昨天,測試程序時,發現程序了java.nio.BufferOverflowException 異常,后來,在網上搜索了資料,終于解決了問題。這里記錄一下。


ByteBuffer params = ByteBuffer.allocate(2);// 這里只分配了2個字節,下面的params.put(tmp);卻put了3個字節的數據。所以導致 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);


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

如何解決這個問題呢?

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

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


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

總結

當 ByteBuffer.remaining()??小于要讀取或寫入的長度時,再執行讀取或寫入操作都會產生異常;

讀取則產生?java.nio.BufferUnderflowException?異常,

寫入則產生?java.nio.BufferOverflowException?異常。

當?ByteBuffer.remaining()??等于 0 時,不能再執行讀取或寫入操作,需要執行:clear() 操作,否則將產生異常。


這里介紹一下幾個Buffer的函數

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

使用get()從緩沖區中取數據,使用put()向緩沖區中存數據。

// 創建一個容量為10的byte數據緩沖區ByteBuffer buff = ByteBuffer.allocate(10);// 存入4次數據buff.put((byte) 'A');buff.put((byte) 'B');buff.put((byte) 'C');buff.put((byte) 'D');// 翻轉緩沖區buff.flip();// 讀取2次數據System.out.println((char)buff.get());System.out.println((char)buff.get());


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

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

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


再向Buffer中讀寫數據時有2個方法也非常有用:

Buffer.remaining():返回從當前位置到上界的數據元素數量;

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


2、翻轉(Buffer.flip())

??????? 翻轉就是將一個處于存數據狀態的緩沖區變為一個處于準備取數據的狀態,使用flip()方式實現翻轉。Buffer.flip()的源碼如下:

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


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

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


3、壓縮(Buffer.compact())

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

// 創建一個容量為10的byte數據緩沖區ByteBuffer buff = ByteBuffer.allocate(10);// 填充緩沖區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()));//翻轉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()));//繼續填充buff.put((byte)'E');buff.put((byte)'F');//輸出所有System.out.println("put after compact : " + new String(buff.array()));


以上代碼打印結果:

first put : ABCD

A

B

compact after get : CDCD

put after compact : CDEF

控制臺中輸出內容中有正方形的亂碼,是正常。因為字節緩沖區中沒有賦值的內存塊默認值是0,而Unicode編碼中沒有0編碼,所以亂碼。


這里簡單這里一下:

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


















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


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


就這么簡單。


總結

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

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