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