美文网首页程序员
学习笔记——NIO(2)关于Buffer

学习笔记——NIO(2)关于Buffer

作者: AceCream佳 | 来源:发表于2017-05-15 14:47 被阅读0次

Buffer是缓存,Buffer的作用是和NIO通道(Channel)进行交互。
查阅资料知道:

缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存。这块内存被包装成NIO Buffer对象,并提供了一组方法,用来方便的访问该块内存。

Buffer的使用

总共分为四步:
1.写数据到Buffer
2.调用flip()方法
3.从Buffer中读取数据
4.调用clear()方法或者compact()方法
上一篇文章写Channel测试的时候也简单使用了Buffer。这里说一下clear()和compact()方法。他们都可以在读取完毕之后清空缓存区,为以后的数据写入做准备,他们的区别在于:clear()方法会清空整个缓冲区。compact()方法只会清除已经读过的数据。未读过的数据会留在缓存区中,随着后面读入的数据一起等下一次的filp()。

这里用代码简单的使用一下:

public class TestBuffer {
    public static void main(String[] args) throws IOException {
        Charset charset = Charset.forName("utf-8");
        CharsetDecoder decoder = charset.newDecoder();
        RandomAccessFile file = new RandomAccessFile("nio-data.txt","rw");
        FileChannel channel = file.getChannel();
        ByteBuffer buf = ByteBuffer.allocate(48);
        CharBuffer cb = CharBuffer.allocate(48);
        int count = channel.read(buf);
        while (count!=-1){
            buf.flip();
            decoder.decode(buf,cb,false);
            cb.flip();
            while (cb.hasRemaining()){
                System.out.print(cb.get());
            }
            buf.compact();
            cb.compact();
            count = channel.read(buf);
        }
        file.close();
    }
}

这里我开始使用compact()而不是clear()了。

接下来学习一下Buffer的原理

它有三个重要的属性:

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

position和limit的含义取决于Buffer处在读模式还是写模式。
capacity不然。

capacity(容量)

翻译来是容量,很好理解,既然是容量就又固定的大小,一旦Buffer满了,我们就需要对其清空,然后才能继续使用它。

position(位置)

写模式:position表示数据当前的位置,会随着数据的写入不断的移动,直到达到容量,position最大为capacity-1。
读模式:当我们读取数据时,Buffer会从写模式切换到读模式,然后position会清0,position会移动到可读的位置。

limit(界限)

写模式:limit表示我们还能向Buffer中写多少数据,此模式下limit等于capacity。
读模式:此模式下,limit表示我们可以从Buffer度多少数据,此时limit会设置为写模式下的position值。

其实有数据结构的线性结构的思想,理解起来就会很简单,可以通过复习数组、链表、队列和栈来回忆~

Buffer使用(细化)

为Buffer分配空间

前面练习有对Buffer分配空间的代码,这里提取出来单独记:

ByteBuffer buf = ByteBuffer.allocate(48);

这就分配好了,这里只是Byte类型,我们还可以使用很多基本类型的buffer,就是可以通过char,short,int,long,float 或 double类型来操作缓冲区中的字节。

向Buffer写数据

我们可以选择两种方式去写数据:
1.用Channel向Buffer写

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

2.用Buffer自带的put()方法

buf.put(127);

从Buffer读数据

这之前先说个filp()方法,filp()这个办法,会将Buffer从写模式切换成读模式,将position设置为0,并将limit设置成之前position的值,也就是说:position现在用于标记读的位置,limit表示之前写进了多少个byte、char等 —— 现在能读取多少个byte、char等。
读数据也有两种方式:
1.从Channel里读

int bytesWritten = inChannel.write(buf);

2.用Buffer的get()方法

byte aByte = buf.get();
记一下rewind()方法

Buffer.rewind()会将position设回0,所以使用后,我们可以重读Buffer中的所有数据。

记一下clear()与compact()方法

前面有简单的记过,这里具体说一说,当我们读完buffer中的数据之后,要将缓存清空,这时候就需要使用到这俩方法,可以根据实际情况任选其一~
clear()是清除所有的缓存。
compact()是清除已经读过的缓存。
clear()会把position设回0,limit被设置成 capacity的值。
compact()将position设到最后一个未读元素正后面。limit属性依然像clear()方法一样,设置成capacity。

记一下mark()与reset()方法
buffer.mark();
buffer.reset();

通过调用Buffer.mark()方法,可以标记Buffer中的一个特定position。之后可以通过调用Buffer.reset()方法恢复到这个position。

equals()与compareTo()方法

先说equals()
Q:什么情况下equals()返回true呢?
A:需要满足以下情况:
1.类型相同
2.Buffer中剩余的byte、char等的个数相同
3.Buffer中所有剩余的byte、char等都相同。
所以Buffer中,equals(),比较的是Buffer的剩余部分

Q:compareTo()方法是啥?
A:compareTo是比较两个Buffer的剩余元素的(byte、char等)
什么情况下一个Buffer小于另一个Buffer呢?
1.第一个不相等的元素小于另一个Buffer中对应的元素 。
2.所有元素都相等,但第一个Buffer比另一个先耗尽(第一个Buffer的元素个数比另一个少)。


Scatter和Gather

这里yi

相关文章

网友评论

    本文标题:学习笔记——NIO(2)关于Buffer

    本文链接:https://www.haomeiwen.com/subject/rcgcxxtx.html