2019独角兽企业重金招聘Python工程师标准>>>

ByteBuffer 是jdk内部提供的字节缓冲区,内存分配主要分为堆内存和直接内存(堆外内存)。

1、堆内存分配

//分配一个容量为32的堆缓冲区
ByteBuffer buffer = ByteBuffer.allocate(32);

2、直接内存

ByteBuffer buffer = ByteBuffer.allocateDirect(32);

字节数据操作

ByteBuffer 有4个属性 capacity、limit、position、mark

capacity:容量,即可以容纳的最大数据量;在缓冲区创建时被设定并且不能改变。

limit:表示缓冲区的当前终点,不能对缓冲区超过极限的位置进行读写操作。可以通过下面的方法修改

public final Buffer limit(int newLimit)

position: 位置,下一个要被读或写的元素的索引,每次读写缓冲区数据时都会改变改值,为下次读写作准备。可以通过下面的方法修改

public final Buffer position(int newPosition)

mark标记: 调用mark()来设置mark=position,再调用reset()可以让position恢复到标记的位置

示例代码:

    @Testpublic void test(){//分配一个容量为32的堆缓冲区ByteBuffer buffer = ByteBuffer.allocate(32);//初始状态System.out.println(String.format("初始状态 limit:%d,capacity:%d,position:%d",buffer.limit(),buffer.capacity(),buffer.position()));//添加字节buffer.put("hello".getBytes());//输出System.out.println(String.format("添加字节后 limit:%d,capacity:%d,position:%d",buffer.limit(),buffer.capacity(),buffer.position()));//读取的内容是position到limit之间数据 调用该方法设置 limit = position;position = 0;mark = -1;buffer.flip();//输出System.out.println(String.format("flip后--》 limit:%d,capacity:%d,position:%d",buffer.limit(),buffer.capacity(),buffer.position()));//读取数据byte[] newArray = new byte[buffer.remaining()] ;buffer.get(newArray);String value = new String(newArray);System.out.println("读取到的数据:"+value);System.out.println(String.format("读取后--》 limit:%d,capacity:%d,position:%d",buffer.limit(),buffer.capacity(),buffer.position()));//调用mark标记当前position的值buffer.mark();//设置limit的值 position到limit的长度为可写的长度 所有设置为buffer.position()+新字节的长度buffer.limit(buffer.position()+"abcdef".getBytes().length);buffer.put("abcdef".getBytes());//写入后position会向后移动 position=limitSystem.out.println(String.format("再次写入后--》 limit:%d,capacity:%d,position:%d",buffer.limit(),buffer.capacity(),buffer.position()));//读取新写入的内容,需要将position设置为mark的位置buffer.reset();System.out.println(String.format("再次读取reset后--》 limit:%d,capacity:%d,position:%d",buffer.limit(),buffer.capacity(),buffer.position()));//读取数据byte[] newArray2 = new byte[buffer.remaining()] ;buffer.get(newArray2);String value2 = new String(newArray2);System.out.println("读取到的数据:"+value2);System.out.println(String.format("读取后--》 limit:%d,capacity:%d,position:%d",buffer.limit(),buffer.capacity(),buffer.position()));}

运行结果:

分析:

1、向一个容量为32的字节缓冲区中写入hello字符后,position=5

2、读取写入的字节必须调用flip,调用后limit = position=5;position = 0;mark = -1;

然后调用下面的方法去读取缓冲区的数据。buffer.remaining()=limit - position,读取的内容是从position到limit之间的内容。

byte[] newArray = new byte[buffer.remaining()] ;
buffer.get(newArray);

3、读取后,position指针会向后移动,position=limit

4、再次写入字节abcdef,需要调用mark方法,记录一下当前position的值

设置limit的值为(position+abcdef的长度),然后调用put方法写入字节。

调用buffer.reset(); 将position设置为mark的值(5)

最后读取position与limit之间的字节数据就是abcdef。

Buffer方法汇总:

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

转载于:https://my.oschina.net/suzheworld/blog/3007051

NIO-ByteBuffer相关推荐

  1. java.nio.ByteBuffer用法小结

    转载自  java.nio.ByteBuffer用法小结 在NIO中,数据的读写操作始终是与缓冲区相关联的.读取时信道(SocketChannel)将数据读入缓冲区,写入时首先要将发送的数据按顺序填入 ...

  2. java bytebuffer 读写_java nio bytebuffer文件读写问题

    为什么下面的代码从文件中读不出3和2来?importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOExc ...

  3. java nio rewind_java.nio.ByteBuffer中的flip()、rewind()、compact()等方法的使用和区别

    java.nio.ByteBuffer 1. ByteBuffer中的参数position.limit.capacity.mark含义: position:表示当前指针的位置(下一个要操作的数据元素的 ...

  4. hbase 2.4 java.lang.NoSuchMethodError: java.nio.ByteBuffer.rewind()Ljava/nio/ByteBuffer

    hbase 2.4集群环境启动报错,java.lang.NoSuchMethodError: java.nio.ByteBuffer.rewind()Ljava/nio/ByteBuffer ​ 详细 ...

  5. java byte 释放内存_java java.nio.ByteBuffer.allocateDirect 导致内存泄露

    java能够经过java.nio.ByteBuffer.allocateDirect(capacity)直接运用non java heap(java堆外)的内存 . 一.运用意图: 1.拓荒数据缓冲区 ...

  6. NIO ByteBuffer 的 allocate 和 allocateDirect 的区别(HeapByteBuffer 和 DirectByteBuffer 的区别)

    ByteBuffer 中 NIO里用得最多的Buffer ,有两种实现方式:HeapByteBuffer基于Java堆的实现,而DirectByteBuffer 使用了 unsafed 的API 进行 ...

  7. NIO ByteBuffer的allocate与allocateDirect区别(HeapByteBuffer与DirectByteBuffer的区别)

    在Java中当我们要对数据进行更底层的操作时,一般是操作数据的字节(byte)形式,这时经常会用到ByteBuffer这样一个类. ByteBuffer提供了两种静态实例方式: public stat ...

  8. Classloader、NIO ByteBuffer.allocateDirect的回收 、一致性Hash

    比较多的东西,写的比较杂乱,以后会写一些自己复习到的内容,或者新学习到的东西,尽量让自己写的东西有价值,对一天学习的内容有一个总结. 一.Classloader 1.过程 1)加载:查找并加载类的二进 ...

  9. 13. 一步一图带你深入剖析 JDK NIO ByteBuffer 在不同字节序下的设计与实现

    一步一图带你深入剖析 JDK NIO ByteBuffer 在不同字节序下的设计与实现 让我们来到微观世界重新认识 Netty 在前面 Netty 源码解析系列 <聊聊 Netty 那些事儿&g ...

  10. 一步一图带你深入剖析 JDK NIO ByteBuffer 在不同字节序下的设计与实现

    让我们来到微观世界重新认识 Netty 在前面 Netty 源码解析系列 <聊聊 Netty 那些事儿>中,笔者带领大家从宏观世界详细剖析了 Netty 的整个运转流程.从一个网络数据包在 ...

最新文章

  1. centos6.8 安装mysql_Centos6.8通过yum安装mysql5.7
  2. JavaScript 函数定义方式
  3. linux 其他参数
  4. bootstrap --- 弹出对话框
  5. 相对不容易用计算机语言编程实现的是,在描述算法的方法中,相对不容易用计算机语言编程实现的是(    )....
  6. 【壹刊】Azure AD B2C(一)初识
  7. SSH 框架 没加commons-beanutils-1.7.0.jar包的错误提示
  8. 轻量化网络:ShuffleNet V2
  9. 【java笔记】基本类型与字符串之间的转换
  10. c语言 int操作bit,C语言,使用共用体和结构体 查看int型的bit散布
  11. IT趣谈:关于所谓”XcodeGhost”的澄清
  12. 计算机管理员账户权限不足,用户权限不足,请使用管理员权限。怎么办啊?求高手帮忙!谢了。...
  13. CSDN和Typora的Markdown插入思维导图
  14. 到底什么是数据中台?
  15. linux下刻录光盘读取不了_Linux下刻录光盘
  16. 设有4x4的方阵,其中的元素由键盘输入。分别求出主对角线上元素之和、辅对角线上元素之积、方阵中最大的元素。
  17. android 投屏截图,手机投屏到电脑上怎样截图?图片格式可以这样设置
  18. oracle中有没有distance,oracle_关于extended distance cluster  rac的介绍
  19. python pip 的安装、更新、卸载、降级、和使用 pip 管理包
  20. ANDROID 65536错误

热门文章

  1. [转载] 使用python 中的numpy创建数组
  2. SignalR 跨域解决方案全面
  3. 【NOI2014】魔法森林
  4. 100. Same Tree (Tree;DFS)
  5. 兔子--html,js,php,ASP,ASP.NET,JSP的关系
  6. hdu5618 (三维偏序,cdq分治)
  7. Xfire的aegis绑定方式配置小结
  8. python---之os.path.splitext(“文件路径”)
  9. ESP8266_APP连接试验
  10. 任天堂 虚拟主机服务器,任天堂 虚拟主机服务器