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在文件 ...
随机推荐
- swift hidesBottomBarWhenPushed 设置界面
方法一(推荐):一级界面push的时候设置,子页面无需设置 let vc = JYMyCommissionController() vc.hidesBottomBarWhenPushed = true ...
- NCUAP 利用java自带方法实现导入excel取数据
final JComponent parent = getModel().getContext().getEntranceUI(); JFileChooser chooser = new JFileC ...
- Java 日志体系
Java 日志体系 <java 日志和 SLF4J 随想>:http://ifeve.com/java-slf4j-think/ 一.常用的日志组件 名称 jar 描述 log4j log ...
- 【Mysql】事务的四种特性和隔离级别
四种特性: 原子性(Atomicity):事务里所有操作视为一个整理,要么全部完成,要么全回滚. 一致性(Consistency):操作前后,数据库内数据逻辑上一致.比如:1w元转账给不同的人,转出去 ...
- SpringBoot编写自定义Starter
根据SpringBoot的Starter编写规则,需要编写xxxStarter依赖xxxAutoConfigurer,xxxStarter是一个空的jar,仅提供辅助性的依赖管理,引入其他类库 1.建 ...
- python 更换 版本
这是一个悲伤的安装ipython的过程. 写下来留个教训吧. 也是希望对博友一些帮助吧. 注: 我也写了一篇window下安装bpython的文章(个人感觉bpython要比ipython强大的多), ...
- diff 命令详解
[自注:] 1,还有个colordiff命令,用颜色标识不同的地方.需要先安装 2,diff normal模式中 2,5表示从第二行到第五行 3,diff -c 模式中,2,5表示从第二行到第五行 4 ...
- IntelliJ IDEA 2017版 spring-boot2.0.2 搭建 JPA springboot DataSource JPA sort排序方法使用方式, 添加关联表的 order by
1.sort可以直接添加在命名格式的字段中 List<BomMain> findAllByDeleted(Integer deleted, Sort sort); 2.可以作为pageab ...
- 125 open source Big Data architecture papers for data professionals
https://www.linkedin.com/pulse/100-open-source-big-data-architecture-papers-anil-madan
- 2019-4-22 jdbc学习笔记
jdbc 一.定义:java database connector 二.常用的接口 java.sql.Driver 驱动 java.sql.Connection 链接 java.sql.State ...