Java NIO中的缓冲区Buffer(二)创建/复制缓冲区
创建缓冲区的方式
主要有以下两种方式创建缓冲区:
1、调用allocate方法
2、调用wrap方法
我们将以charBuffer为例,阐述各个方法的含义;
allocate方法创建缓冲区
调用allocate方法实际上会返回new HeapCharBuffer(capacity, capacity)对象;
缓存空间存储在CharBuffer类的成员属性char[] hb数组里,即JVM堆里;
如下示例,创建了一个容量大小为10的CharBuffer:
CharBuffer bf = CharBuffer.allocate(10);
allocate方法其实比较简单,不过有点需要注意的是,allocate方法除了可以分配JVM堆空间,还可以分配直接内存空间(如ByteBuffer,可以调用allocateDirect方法分配直接内存),其内部是通过调用unsafe.allocateMemory方法实现直接内存分配的,该空间不在JVM堆内部,后续会做更加详细的说明;不过可以稍微提醒一点,如果是直接内存空间的话,调用hasArray()方法会返回false;
wrap方法创建缓冲区
调用wrap方法实际上会也会返回new HeapCharBuffer(array, offset, length)对象;
与allocate方法的区别是,它的缓存存储空间是外部传入的;
如下示例,创建了一个容量大小为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;

复制缓冲区的方式
主要有以下三种方式复制缓冲区:
1、调用duplicate方法
2、调用asReadOnlyBuffer方法
3、调用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);
该缓存区与原始缓存区共享一段序列;
如下示例:
1、我们先创建一个容量为10的缓存区charbuffer1
CharBuffer charbuffer1 = CharBuffer.allocate(10);
此时:mark = -1; position = 0; limit = 10; capacity = 10;

2、修改charbuffer1的position和limit值
charbuffer1.position(2).limit(5);
此时:mark = -1; position = 2; limit = 5; capacity = 10;

3、调用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》
Java NIO中的缓冲区Buffer(二)创建/复制缓冲区的更多相关文章
- Java NIO中的缓冲区Buffer(一)缓冲区基础
什么是缓冲区(Buffer) 定义 简单地说就是一块存储区域,哈哈哈,可能太简单了,或者可以换种说法,从代码的角度来讲(可以查看JDK中Buffer.ByteBuffer.DoubleBuffer等的 ...
- java NIO中的buffer和channel
缓冲区(Buffer):一,在 Java NIO 中负责数据的存取.缓冲区就是数组.用于存储不同数据类型的数据 根据数据类型不同(boolean 除外),提供了相应类型的缓冲区:ByteBufferC ...
- Java NIO中的Buffer 详解
Java NIO中的Buffer用于和NIO通道进行交互.如你所知,数据是从通道读入缓冲区,从缓冲区写入到通道中的.缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这块内存被包装成NIO ...
- Java NIO中核心组成和IO区别
1.Java NIO核心组件 Java NIO中有很多类和组件,包括Channel,Buffer 和 Selector 构成了核心的API.其它组件如Pipe和FileLock是与三个核心组件共同使用 ...
- java输入输出 -- java NIO之缓存区Buffer
一.简介 java NIO相关类在jdk1.4被引入,用于提高I/O的效率.java NIO包含很多东西,但核心的东西不外乎Buffer.channel和selector.本文先来看Buffer的实现 ...
- Java NIO学习-详细内容(二)
五.Selector与SelectionKey Selector是SelectableChannel 对象的多路复用器,为什么使用Selector? 仅用单个线程来处理多个Channels的好处是,只 ...
- 转:Java NIO系列教程(三) Buffer
Java NIO中的Buffer用于和NIO通道进行交互.如你所知,数据是从通道读入缓冲区,从缓冲区写入到通道中的. 缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这块内存被包装成NIO ...
- Java NIO(三) Buffer
Java NIO中的Buffer用于和NIO通道进行交互.如你所知,数据是从通道读入缓冲区,从缓冲区写入到通道中的. 缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这块内存被包装成NIO ...
- 转载Java NIO中的Files类的使用
Java NIO中的Files类(java.nio.file.Files)提供了多种操作文件系统中文件的方法. Files.exists() Files.exits()方法用来检查给定的Path在文件 ...
随机推荐
- 关于TP5.0搜索后分页
使用$Model->where($where)->paginate($page,$count);的时候如果点击下一页会出现条件重置问题,经过测试可以使用Db::name('data') - ...
- 258. Add Digits 入学考试:数位相加
[抄题]: Given a non-negative integer num, repeatedly add all its digits until the result has only one ...
- 记录一次Centos磁盘空间占满的解决办法(转)
原文地址:https://blog.csdn.net/everything1209/article/details/70209157 解决前 磁盘使用情况: 第二块磁盘使用率达到97% [root@f ...
- Quartz.NET快速入门指南
最近,在工作中遇到了 Quartz.net 这个组件,为了更好的理解项目代码的来龙去脉,于是决定好好的研究一下这个东西.确实是好东西,既然是好东西,我就拿出来分享一下.万丈高楼平地起,我们也从入门开始 ...
- swap的实现(没有中间变量)
两数交换最常用的方法 void swap(int &a,int &b) { int temp=a; a=b; b=temp; } 如果没有中间变量temp可以使用呢,还有其他的三种方法 ...
- 查看memcached进程
- List,set,Map理解
集合 集合与数组 数组(可以存储基本数据类型)是用来存现对象的一种容器,但是数组的长度固定,不适合在对象数量未知的情况下使用. 集合(只能存储对象,对象类型可以不一样)的长度可变,可在多数情况下使用. ...
- 2019.02.12 bzoj3944: Sum(杜教筛)
传送门 题意: 思路:直接上杜教筛. 知道怎么推导就很简单了,注意预处理的范围. 然后我因为预处理范围不对被zxyoi教育了(ldx你这个傻×两倍常数活该被卡TLE) 喜闻乐见 代码: #includ ...
- IDEA中MyBaits的Mapper文件颜色问题
IDEA中MyBaits的Mapper文件颜色问题 在IDEA中Mapper文件的展示 包含的警告及其解决方案 然后我们就完成了,效果如下 在IDEA中Mapper文件的展示 在IDEA中,Mappe ...
- HDU 2639 01背包(分解)
http://acm.hdu.edu.cn/showproblem.php?pid=2639 01背包第k优解,把每次的max分步列出来即可 #include<stdio.h> #incl ...