第四节 netty前传-NIO中缓冲buffer-02
2018-10-17 本文已影响5人
勃列日涅夫
上一节中基本上已经介绍过buffer的核心部分,本节介绍buffer的几种很常用的api
- 获取Buffer对象,并初始化
要获取Buffer对象,必须先分配它。 每个Buffer类都有一个allocate()方法来
初始化一个缓冲区,大小为1024byte
ByteBuffer buf = ByteBuffer.allocate(1024);
- 向Buffer对象中写入数据
一般会有两种方式向buffer对象中写入数据,一种是通过Channel 写入,另外一种是buffer自身的api
使用put方法
第一种:int bytesRead = fileChannel.read(buf);
第二种:buf.put(2);
-
flip()方法
前面已经说过flip() 方法将Buffer从写入模式切换到读取模式时。 将limit设置为写模式的位置,同时会将positon设置回0。 -
从buffer读取数据
和写入相似,也有两种方式。其一是通过channel中读取buffer中的数据,其二时直接通过buffer自身get方法读取
//read from buffer into channel.
int bytesWritten = inChannel.write(buf);
//直接读取
byte aByte = buf.get();
- rewind()方法
rewind方法将position设置回0,因此可以重读缓冲区中的所有数据。并且limit保持不变,因此仍然标记可以从缓冲区读取多少元素(字节,字符等)。 - clear() 和compact()
这俩方法上一节也说过了,都是清除buffer中已读数据,准备开始写入。不同的是,clear方法会将position标记为0,意味着从头开始写入也会覆盖之前buffer中未读的数据。compact不同之处在于,它会将未读的数据移到buffer的开头,然后会将postion标记为这些未读的数据之后,这样写入数据就不会覆盖这些未读的数据。换句话说如果仍然想读取之前未读的数据就用compact,否则使用clear方法 - mark() 和 reset()
一般来说这两个方法是成对出现,通过调用Buffer.mark() 方法会在Buffer中标记当前的位置,下面是 Buffer类中两个方法的源码。 通过调用Buffer.reset() 方法将位置重置回标记位置。
/**
* Sets this buffer's mark at its position.
*/
public Buffer mark() {
mark = position;
return this;
}
/**
* Resets this buffer's position to the previously-marked position.
* <p> Invoking this method neither changes nor discards the mark's
* value. </p>
* @return This buffer
* @throws InvalidMarkException
* If the mark has not been set
*/
public Buffer reset() {
int m = mark;
if (m < 0)
throw new InvalidMarkException();
position = m;
return this;
}
使用场景
buffer.mark();//标记当前的位置
buffer.get() //中间可能读取一些数据,然后又想从标记位置再次读取
buffer.reset(); //回到标记位置,就可再次读取
- 最后说一下equals() 和compareTo()方法
比较啷个buffer是否相同,buffer给出以下规定
它们的类型相同(byte,char,int等)
它们在缓冲区中具有相同数量的剩余字节,字符等。
所有剩余的字节,字符等都相等。
equals仅比较缓冲区的一部分,而不是它内部的每个元素。 实际上,它只是比较缓冲区中的其余元素。compareTo()方法比较两个缓冲区的剩余元素(字节,字符等)。 在下列情况下,缓冲区被视为“小于”另一个缓冲区:
1、与另一个缓冲区中的对应元素相等的第一个元素小于另一个缓冲区中的元素。
2、 所有元素都相等,但第一个缓冲区在第二个缓冲区之前耗尽了元素(它有更少的元素)。