【每日一篇】NIO学习【二】什么是Buffer

本文深入讲解了Java中Buffer的工作原理,包括其与Channel的配合使用、核心属性(Capacity、Position和Limit)的意义及其在读写模式下的作用。此外还介绍了各种Buffer的实现,并详细解释了如何使用Buffer进行数据的写入、翻转、读取及清空。
摘要由CSDN通过智能技术生成

    前篇可知Buffer是和Chanel配套使用的,Chanel从Buffer中读数据,将数据写入Buffer.Buffer的实质是块内存,被包装成JAVA Object并提供基础方法使我们可以更简单的使用。

熟悉一下三个属性有助于我们理解Buffer是怎样工作的:

  • capacity 容量
  • position  位置
  • limit         界限

这三个属性的在Buffer读和写模式下的意义如图:


Java NIO: Buffer capacity, position and limit in write and read mode.
Buffer capacity, position and limit in write and read mode.

Capacity

Buffer是一块内存,其有固定的大小,我们将这个大小表示为Capacity 我们只能写入这个大小的数据进来,如果Buffer满了,我们必须通过read或者clear方法清空空间才能继续写入。

Position

将数据写入Buffer时,positiion会被初始化为0,随后每写入一位+1,最大可以达到capacity-1的位置。我们可以使用filp方法将Buffer从写模式转为读模式,此时每读出一位+1;

Limit

写模式时,Limit表示我们可以写入多少位数据,此时这个值与capacity值是相当的。

读模式时,该值表示我们可以读多少位数据,当我们将写模式转为读模式时,limit值会被设为当时的position值。


有很多种Buffer实现,如下:

  • ByteBuffer
  • MappedByteBuffer
  • CharBuffer
  • DoubleBuffer
  • FloatBuffer
  • IntBuffer
  • LongBuffer
  • ShortBuffer

我们可以使用如下的allocate方法获得一个Buffer对象并为其分配内存空间

ByteBuffer buf = ByteBuffer.allocate(48);

写入Buffer

有两种方法

  1. 使用Chanel写入
  2. 使用Buffer的put方法

法一,将Chanel(数据源)中的数据读入Buffer(缓存区

int bytesRead = inChannel.read(buf); //read into buffer.

法二,调用put方法,该方法有多种变种

buf.put(127);    

flip()

如上文所述,filp()方法可以让Buffer从写模式转为读模式,也就是将limit位置设为position位置,将position位置置0.然后我们就可以从position位置开始读Buffer。

读出Buffer

同样有两种方法

  1. 将Buffer数据读入Channel
  2. 调用Buffer自带的get方法

法1:将Buffer数据读出到channel中(对于channel来说是写入channel,对Buffer当然是读出)

//read from buffer into channel.
int bytesWritten = inChannel.write(buf);

法2:get方法,该方法有多种变种

byte aByte = buf.get();    

rewind()

将position置0。

clear() and compact()

可以调用clear或者compact方法来清空Buffer。

clear方法:position置0,limit置于capacity值。也就是回到Buffer刚分配的状态。

compact方法:如果还有未读的数据在Buffer中,将这些未读数据移至Buffer起点,将position放在最后一个未读数据后面,这样写新数据时就不会覆盖旧数据。

mark() and reset()

实际上buffer中还有一个临时标记位变量mark,mark的值必须小于或等于position。mark方法可以将mark值设为position值,调用reset方法可以将position值回复到标记的位置(也就是mark值)

buffer.mark();

//call buffer.get() a couple of times, e.g. during parsing.

buffer.reset();  //set position back to mark.    

equals() and compareTo()

equal的要求是Buffer同类,Buffer大小相等,Buffer内全部元素相等。

compareTo,逐一比较Buffer内元素大小,如果比不出来就看哪个Buffer先取光元素




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值