Buffer缓冲区理解(capacity,limit,position)

Buffer在IO中很重要。在旧I/O类库中(相对java.nio包)中的BufferedInputStream、BufferedOutputStream、BufferedReader和BufferedWriter在实现中都运用了缓冲区。
java.nio包公开了Buffer API,使得Java程序可以直接控制和运用缓冲区。

什么是Buffer

缓冲区(Buffer)是预留的一块内存,用来对输入\输出的数据做临时存储。

Buffer好处

1、减少实际的物理读写次数,已块作为单位操作输入\输出,相对于流的每个字节的输入\输出。
2、创建后的缓存去可重用,减少动态分配和回收内存的次数。

Buffer种类

ByteBuffer,MappedByteBuffer,CharBuffer,DoubleBuffer,FloatBuffer,IntBuffer,LongBuffer,ShortBuffer
MappedByteBuffer:继承ByteBuffer,专门用于内存映射。
MappedByteBuffer:操作大文件的方式,其读写性能极高。

Buffer创建

allocate(int capacity):从堆空间中分配一个容量大小为capacity的byte数组作为缓冲区的byte数据存储器,用new HeapIntBuffer创建创建堆内内存,受jvm管控限制。和操作系统交互会多一次拷贝过程,先拷贝到堆外系统内存,然后再去交互。
allocateDirect:用new DirectByteBuffer创建堆外内存。通过操作系统来创建内存块用作缓冲区,能提高io操作速度,但是分配直接缓冲区的系统开销很大,因此只有在缓冲区较大并长期存在,或者需要经常重用时,才使用这种缓冲区。
wrap(byte[] array):通过byte数组进行创建,bytes数组或buff缓冲区任何一方中数据的改动都会影响另一方,

Buffer中有四个重要的参数

capacity:最大容量,永远不能为负数,并且不会变化。
limit:限制,可读写数据限制,永远不能为负数,并且不会大于capacity。
position:位置,下一个读或者写的位置,每次读写改变,永远不能为负数,并且不会大于limit。
mark:标记,调用mark()来设置mark=position,再调用reset()可以让position恢复到标记的位置。

Buffer中参数的位置变化

初始化三个参数的位置如下:
在这里插入图片描述

往Buffer中写入a,b,c三个参数后的改变:
在这里插入图片描述
读取之前要调用flip翻转,翻转后如下:
在这里插入图片描述
读取后,参数位置:
在这里插入图片描述
byteBuffer.clear()后恢复初始位置。数据还在内存中,后续写入会覆盖:
在这里插入图片描述

Buffer常用方法

position():读取position的值

position(int newPosition):设置position的值

limit():读取limit的值

limit(int newLimit):设置limit的值

capacity():获取capacity的值

mark():标记,将position赋值给mark

reset():把position设置成mark的值,相当于之前做过一个标记,现在要退回到之前标记的地方。

clear():position = 0;limit = capacity;mark = -1; 初始化,但是并不影响底层byte数组的内容。

flip():limit = position;position = 0;mark = -1; 翻转,就是将一个处于存数据状态的缓冲区变为一个处于准备取数据的状态。

rewind():position = 0;mark = -1; 把position设为0,mark设为-1

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

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值