Java NIO中的缓冲区Buffer(二)建立/复制缓冲区

建立缓冲区的方式

主要有如下两种方式建立缓冲区:java

一、调用allocate方法数组

二、调用wrap方法缓存

咱们将以charBuffer为例,阐述各个方法的含义;spa

allocate方法建立缓冲区

调用allocate方法实际上会返回new HeapCharBuffer(capacity, capacity)对象;code

缓存空间存储在CharBuffer类的成员属性char[] hb数组里,即JVM堆里;对象

以下示例,建立了一个容量大小为10的CharBuffer:blog

CharBuffer bf = CharBuffer.allocate(10);

allocate方法其实比较简单,不过有点须要注意的是,allocate方法除了能够分配JVM堆空间,还能够分配直接内存空间(如ByteBuffer,能够调用allocateDirect方法分配直接内存),其内部是经过调用unsafe.allocateMemory方法实现直接内存分配的,该空间不在JVM堆内部,后续会作更加详细的说明;不过能够稍微提醒一点,若是是直接内存空间的话,调用hasArray()方法会返回false;ip

wrap方法建立缓冲区

调用wrap方法实际上会也会返回new HeapCharBuffer(array, offset, length)对象;内存

与allocate方法的区别是,它的缓存存储空间是外部传入的;ci

以下示例,建立了一个容量大小为10的CharBuffer:

        char[] myArray = new char[10];
        CharBuffer charbuffer = CharBuffer.wrap(myArray);

另外,wrap还有一个重载方法:带offset和length做为参数的wrap()方法,以下是该方法的一个示例:

        char[] myArray = new char[10];
        CharBuffer charbuffer = CharBuffer.wrap (myArray, 2, 3);

以上代码将会建立一个position = 2, limit = 5, capacity = 10的Buffer;

复制缓冲区的方式

主要有如下三种方式复制缓冲区:

一、调用duplicate方法

二、调用asReadOnlyBuffer方法

三、调用slice方法

咱们将以charBuffer为例,阐述各个方法的含义;

duplicate方法复制缓冲区

调用duplicate方法实际上会建立原缓存区的一个拷贝,不是深拷贝,是浅拷贝,什么意思呢,就是这两个缓存区会共享数据元素,但每一个缓存区的上界、容量、位置等属性是各自独立的;

修改其中一个缓存区的元素会影响另外一个拷贝缓存区,以下示例:

        CharBuffer charbuffer1 = CharBuffer.allocate(10);
        CharBuffer charbuffer2 = charbuffer1.duplicate();

        charbuffer1.put('a').put('b').put('c');
        charbuffer1.flip();

        System.out.println(charbuffer1);
        System.out.println(charbuffer2);

charbuffer2缓存区复制了charbuffer1缓存区,至始至终咱们只操做charbuffer1缓存区,最后打印的时候,却发现charbuffer2缓存区里已经有了charbuffer1缓存区的数据,结果打印以下:

abc
abc

asReadOnlyBuffer方法复制缓冲区

调用asReadOnlyBuffer方法会生成一个只读缓存区,与调用duplicate方法基本一致,惟一的区别是这个缓存区是只读的,若对其进行put操做的话,会抛出ReadOnlyBufferException;

以下示例:

        CharBuffer charbuffer1 = CharBuffer.allocate(10);
        CharBuffer charbuffer2 = charbuffer1.asReadOnlyBuffer();

        charbuffer1.put('a').put('b').put('c');
        charbuffer1.flip();

        System.out.println(charbuffer1);
        System.out.println(charbuffer2);

        charbuffer2.put('c');//ReadOnlyBufferException

输出结果:

abc
abc
Exception in thread "main" java.nio.ReadOnlyBufferException
    at java.nio.HeapCharBufferR.put(HeapCharBufferR.java:166)
    at nio.Main.main(Main.java:21)

slice方法复制缓冲区

slice方法实际上是用于分割缓存区的,该方法建立了一个从原始缓冲区的当前位置开始的新缓冲区,而且其容量是原始缓冲区的剩余元素数量(limit-position);

该缓存区与原始缓存区共享一段序列;

以下示例:

一、咱们先建立一个容量为10的缓存区charbuffer1

CharBuffer charbuffer1 = CharBuffer.allocate(10);

此时:mark = -1; position = 0; limit = 10; capacity = 10;

二、修改charbuffer1的position和limit值

charbuffer1.position(2).limit(5);

此时:mark = -1; position = 2; limit = 5; capacity = 10;

三、调用slice方法,对charbuffer1缓存区进行分割

CharBuffer charbuffer2 = charbuffer1.slice();

此时:

charbuffer1:mark = -1; position = 2; limit = 5; capacity = 10;

charbuffer2:mark = -1; position = 0; limit = 3; capacity = 3;

 

 参考资料

《Java NIO》

相关文章
相关标签/搜索