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在文件 ...
随机推荐
- laravel简书(1)
Laravel的社区生态 中文社区(http://laravel-china.org) 5.4中文文档(http://d.laravel-china.org/docs/5.4) Laravel源码地址 ...
- 微信H5开发
1,line-height 不垂直居中 解决方法:用padding写高度 2,手指滑动事件 touchmove 3,页面滚动事件:touchmove 4,要写不同手机适配的基数font-siz ...
- 23. pt-slave-delay
略过,用原生的延迟复制: stop slave; change master to master_delay=5; start slave;
- hdu-1878(欧拉回路)
题目链接:传送门 思路:就是判断无向图的欧拉回路的两个条件:(1)连通性(2)点的度数是偶数 注意:两个条件一同时满足才行. #include<iostream> #include< ...
- 用Dockerfile创建镜像--自动化部署tomcat+mysql+mycat
https://www.jianshu.com/p/a14b34386b41
- tab下图片要求
下面是每个tab的属性: 属性 类型 必填 说明 pagePath String 是 页面路径,必须在pages中先定义 text String 是 tab上按钮文字 iconPath String ...
- ·通过wifi_scan学习esp32wifi程序编写
在ESP32的设计开发中,我们必然会需要使用到wifi或ble功能,今天就讲解下如何将WIFI功能纳入到ESP32中来. 初始化WiFi环境 首先,WiFi子系统的初始化需要由我们自己来自行,当我们写 ...
- Centos7.0进入单用户模式修改root密码
启动Centos7 ,按空格让其停留在如下界面. 按e进行编辑 在UTF-8后面输入init=/bin/sh 根据提示按ctrl+x 得如下图 输入mount -o remount,rw / 然后输 ...
- 还原一直卡在ASYNC_IO_COMPLETION浅析
下面在还原一个数据库(备份文件40多G大小,实际数据库大小300G),在还原过程中,出现一直等待ASYNC_IO_COMPLETION,如下测试截图所示,已经等待了72分钟了,但是还原比例依然为0% ...
- Visual Studio 代码片段
管理界面 打开 工具 >> 代码片段管理器 界面 使用步骤 选择对应语言. 选择一个片段的文件夹. 打开该文件夹的位置. 复制任意一个片段. 对复制出来的片段进行修改.(具体修改内容见例子 ...