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在文件 ...
随机推荐
- 258. Add Digits 入学考试:数位相加
[抄题]: Given a non-negative integer num, repeatedly add all its digits until the result has only one ...
- Mobile Computing: the Next Decade论文 cloudlet薄云
1 Introduction “Information at your fingertips anywhere, anytime” has been the driving vision of mob ...
- 三 分析easyswoole源码(启动服务&TableManager,略提及Cache工具的原理)
前文连接,讲了es是如何启动swoole服务的. 里面有一个工具类TableManager.这个类为了处理进程间数据共享.是对swoole_table的一层封装swoole_table一个基于共享内存 ...
- Python程序中的进程操作
之前我们已经了解了很多进程相关的理论知识,了解进程是什么应该不再困难了,刚刚我们已经了解了,运行中的程序就是一个进程.所有的进程都是通过它的父进程来创建的.因此,运行起来的python程序也是一个进程 ...
- HDU 5521.Meeting 最短路模板题
Meeting Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total ...
- Python之ftp服务器
今天把做的ftp服务器过程总结一下,先看看要求 一.需求 1. 用户加密认证 2. 允许同时多用户登录 3. 每个用户有自己的家目录 ,且只能访问自己的家目录 4. 对用户进行磁盘配额,每个用户的可用 ...
- <fieldset>标签
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Conten ...
- Codeforces Round #547 (Div. 3) F 贪心 + 离散化
https://codeforces.com/contest/1141/problem/F2 题意 一个大小为n的数组a[],问最多有多少个不相交的区间和相等 题解 离散化用值来做,贪心选择较前的区间 ...
- 单台机器安装zookeeper
先给一堆学习文档,方便以后查看 官网文档地址大全: OverView(概述) http://zookeeper.apache.org/doc/r3.4.6/zookeeperOver.html Get ...
- 【repost】JavaScript 基本语法
JavaScript 基本语法,JavaScript 引用类型, JavaScript 面向对象程序设计.函数表达式和异步编程 三篇笔记是对<JavaScript 高级程序设计>和 < ...