昨天,测试程序时,发现程序了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 异常相关推荐

  1. Android Unable to execute dex: java.nio.BufferOverflowException

    导入Android项目至Eclipse中,编译项目报错: Unable to execute dex: java.nio.BufferOverflowException. Check the Ecli ...

  2. Java nio 异常_java.nio.BufferOverflowException 异常问题

    系统运行一段时间,tomcat就会一直抛出下面的异常,造成系统不能访问,是什么原因? 2018-11-30 10:20:43,014 org.nutz.mvc.impl.processor.FailP ...

  3. 理解和解决Java并发修改异常ConcurrentModificationException(转载)

    原文地址:https://www.jianshu.com/p/f3f6b12330c1 理解和解决Java并发修改异常ConcurrentModificationException 不知读者在Java ...

  4. 【Bug】解决 java.sql.SQLSyntaxErrorException 异常

    [Bug]解决 java.sql.SQLSyntaxErrorException 异常 参考文章: (1)[Bug]解决 java.sql.SQLSyntaxErrorException 异常 (2) ...

  5. 已解决java.lang.ClassCastException异常的正确解决方法,亲测有效!!!

    已解决java.lang.ClassCastException异常的正确解决方法,亲测有效!!! 文章目录 报错问题 解决方法 福利 报错问题 粉丝群里面的一个小伙伴敲代码时发生了报错(当时他心里瞬间 ...

  6. 已解决java.lang.NoClassDefFoundError异常的正确解决方法,亲测有效!!!

    已解决java.lang.NoClassDefFoundError异常的正确解决方法,亲测有效!!! 文章目录 报错问题 报错原因 解决方法 NoClassDefFoundError解决示例 福利 报 ...

  7. java 并发修改_理解和解决Java并发修改异常ConcurrentModificationException

    your name.jpg 关键字: Java Exception 不知读者在Java开发的过程中有没有遇到类似的异常信息 Exception in thread "main" j ...

  8. Android解决java.lang.OutOfMemoryError: bitmap size exceeds VM budget(转)

    昨天遇到这个问题就是从一个输入流里调用BitmapFactory.decodeStream(this.getContentResolver().openInputStream(uri))得到一个bit ...

  9. 转载 Android解决java.lang.OutOfMemoryError: bitmap size exceeds VM budget

    当图片过大,或图片数量较多时使用BitmapFactory解码图片会出java.lang.OutOfMemoryError: bitmap size exceeds VM budget,要想正常使用则 ...

最新文章

  1. 接口请求时params与data的区别
  2. 请问1到10000之前,有多少升数字?(华图教育面试题)
  3. day04_09 while循环03
  4. java mac 转换 整形_JAVA的整型与字符串相互转换
  5. 注解驱动的 Spring cache 缓存介绍
  6. 揭秘2019双11背后的云网络 – 双11网络架构和洛神系统
  7. [论文阅读][深度学习-三维重建]Single-Shot 3D Shape Reconstruction Using Structured Light and CNN
  8. 案例解读:深入理解浏览器的缓存机制
  9. P3 如何创建数据库数据表
  10. 西邮计算机学院院长,西安邮电大学计算机学院
  11. Ubuntu下安装Flask虚拟环境及使用
  12. 关于Win10系统下VIA HD AUDIO威盛声卡没声音问题 - 有效解决办法
  13. 数据链路层的主要功能
  14. nmap工具进行端口扫描
  15. 一个有用的webstrom激活方法
  16. 用Python实现手机抓包,获取当当图书差评数据!
  17. 7-21 查验身份证 (15 分)
  18. Qt5:报错error: ‘tr‘ was not declared in this scop
  19. 关于罗德里格斯公式(Rodrigues‘sFormula)的详细推导过程
  20. delegation机制

热门文章

  1. Java script第二课
  2. Objective c类的初始化
  3. 《编写高质量代码改善JavaScript程序的188个建议》读书笔记
  4. 计算广告 读书笔记 计算广告的核心问题
  5. 目标检测与转自背景减除
  6. 内网用户之间使用MSN Messenger快速传送文件的小窍门
  7. Vue学习----webpack跨域问题proxyTable
  8. 不依赖远程API启动SEER区块链命令行钱包和网页钱包的方法
  9. 基于Spring读写分离
  10. oracle pl/sql 函数