android 解决java.nio.BufferOverflowException 异常
昨天,測試程序時,發現程序了java.nio.BufferOverflowException 異常,后來,在網上搜索了資料,終于解決了問題。這里記錄一下。
錯誤原因:寫入的長度超出了允許的長度:
如何解決這個問題呢?
添加寫入長度與 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()的源碼如下:
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 异常的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android byte的使用
- 下一篇: android 动态修改控件的宽高