2.Buffer 缓冲区
/*缓冲区(Buffer)*/
Buffer 就像一个数组,可以保存多个相同类型的数据。根据数据类型不同(boolean 除外),有以下Buffer常用子类:
/*ByteBuffer*/(常用) 、CharBuffer 、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer
上述Buffer 类,他们都采用相似的方式进行管理数据,只是各自管理的数据类型不同而已。都是通过如下方法获取一个Buffer对象:
static XxxBuffer allocate(int capacity): 创建一个容量为 capacity 的 XxxBuffer对象
/*缓存区的基本属性*/
Buffer中的重要概念:
1.容量(capacity):表示Buffer 最大数据容量,缓冲区容量不能为负,并且创建后不能修改 (创建Buffer对象时 初始化)
2.限制(limit):第一个不应该读取或写入的数据的索引,(即位于limit后的数据不可读写)缓冲区的限制 不能为负,并且不能大于其容量
3.位置(position):下一个要读取或写入的数据的索引。缓冲区的位置不能为负,并且不能大于其限制值
4.标记(mark)与重置(reset):标记也是一个索引,通过Buffer中的 mark() 方法指定Buffer中一个特定的position,之后可以通过调用reset()方法恢复到这个 position
标记、位置、限制、容量遵循以下不变式:/*0 <= mark <= position <= limit <= capacity*/
Buffer的常用方法
Bufffer clear() 清空缓冲区(索引重置为初始状态)并返回对缓冲区的引用(但是缓冲区的数据依然存在,但是出于 “被遗忘” 状态)
Buffer flip() 将缓冲区的界限设置为当前位置,并将当前位置重置为0 (即准备开始操作缓冲区里面的数据)
缓冲区的数据操作
Buffer 所有子类提供了 两个用于数据操作的方法: get() 与 put() 方法
/*直接与非直接缓冲区*/
非直接缓冲区:通过allocate() 方法 分配缓冲区,将缓冲区建立在 JVM内存中
直接缓冲区: 通过 allocateDirect() 方法 分配直接缓冲区,将缓冲区建立在物理内存中,可以提高效率
字节缓冲区要么是直接的,要么是非直接的。如果是直接字节缓冲区,则Java 虚拟机 会尽最大努力直接在此缓冲区上执行本机 I/O 操作
即直接缓冲区: 通过过一个 ‘物理内存映射文件’ ,将本来要放在JVM内存中的缓冲区 直接放到 物理内存中
非直接缓冲区: 将缓冲区 先放到JVM 的内存中,然后通过 copy ,将内容复制到 内核地址空间(物理内存) ,写入磁盘
直接缓冲区少了一个 copy 的过程,自然速度会更快,但是也有缺点:1.直接在物理内存上开辟和销毁空间的代价很大,2.基本上失去了对缓冲区数据的控制,无法控制其销毁
所以:仅在直接缓冲区能在程序性能方面带来明显好处时分配他们
/*
* 一、缓冲区(Buffer):在Java NIO中负责数据的存取。缓冲区就是数组。用于存储不同数据类型的数据
*
* 根据数据类型不同 (boolean 除外),提供了相应类型的缓冲区
* ByteBuffer(常用) 、CharBuffer、ShortBuffer等
*
* 上述缓冲区 的 管理方式几乎一致,通过 allocate() 获取缓冲区
*
* 二、缓冲区存取数据的两个核心方法:
* put():存入 数据到缓冲区
* get():获取缓冲区的数据
*
* 三、缓冲区的四个核心属性
* 1.capacity : 容量,表示Buffer 最大数据容量,缓冲区容量不能为负,并且创建后不能修改 (创建Buffer对象时 初始化)
*
* 2.限制(limit):第一个不应该读取或写入的数据的索引,(即位于limit后的数据不可读写)
缓冲区的限制 不能为负,并且不能大于其容量
3.位置(position):下一个要读取或写入的数据的索引。缓冲区的位置不能为负,并且不能大于其限制值 4.标记(mark)与重置(reset):标记也是一个索引,通过Buffer中的 mark() 方法指定Buffer中一个特定的position,
之后可以通过调用reset()方法恢复到这个 position
*
* 0 <= mark <= position <= limit <= capacity
*
* 四、直接缓冲区 和 非直接缓冲区
* 非直接缓冲区:通过allocate() 方法 分配缓冲区,将采取建立在 JVM内存中
* 直接缓冲区:通过 allocateDirect() 方法 分配直接缓冲区,将缓冲区建立在物理内存中,可以提高效率
*
* */ public class TestBuffer { @Test
public void test3() {
ByteBuffer buffer1 = ByteBuffer.allocateDirect(1024);
System.out.println(buffer1.isDirect());
ByteBuffer buffer2 = ByteBuffer.allocate(1024);
System.out.println(buffer2.isDirect());
} @Test
public void test2() {
String str = "abcd";
ByteBuffer buffer = ByteBuffer.allocate(1024); buffer.put(str.getBytes()); buffer.flip(); byte[] bytes = new byte[buffer.limit()];
buffer.get(bytes,0,2); //position = 2
System.out.println(new String(bytes));
System.out.println(buffer.position()); //标记当前 position
buffer.mark(); //position = 4
buffer.get(bytes,2,2);
System.out.println(new String(bytes));
System.out.println(buffer.position()); //将 position reset 到 标记的位置 position = 2
buffer.reset();
System.out.println(buffer.position());
} @Test
public void test1() {
//1.分配一个指定大小的缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);
System.out.println("-------------allocate()-------------");
System.out.println(buffer.position());
System.out.println(buffer.limit());
System.out.println(buffer.capacity()); //2.利用 put() 存入数据到缓冲区
String str = "abcedf";
buffer.put(str.getBytes());
System.out.println("-------------put()-------------");
System.out.println(buffer.position()); //此时 位置 索引会变成6,即下一个要读取或写入的数据的索引 是 6 (byte[6])
System.out.println(buffer.limit());
System.out.println(buffer.capacity()); //3.使用 get() 读取数据之前,需要调用 flip() 方法,切换到 读取数据模式 (将position置为0,limit置为原先position)
//不然按照现在的所以 是无法读取到任何数据的
buffer.flip();
System.out.println("-------------flip()-------------");
System.out.println(buffer.position());
System.out.println(buffer.limit());
System.out.println(buffer.capacity()); //4.利用 get() 读取缓冲区中的数据
//读取 需要创建一个容器去装
byte[] bytes = new byte[buffer.limit()];
//将读取到的数据 放到 这个 byte数组中
buffer.get(bytes); System.out.println("-------------get()-------------");
System.out.println(buffer.position());
System.out.println(buffer.limit());
System.out.println(buffer.capacity());
System.out.println(new String(bytes,0,bytes.length)); //5.rewind() 可重复读 将位置设成 0 ,取消设置的 remark,现在就可以重新读取了
buffer.rewind();
System.out.println("-------------rewind()-------------");
System.out.println(buffer.position());
System.out.println(buffer.limit());
System.out.println(buffer.capacity()); //6.clear() 清空缓存区,缓冲区中的数据依然存在,但是 处于 ‘被遗忘’状态
buffer.clear();
System.out.println("-------------clear()-------------");
System.out.println(buffer.position());
System.out.println(buffer.limit());
System.out.println(buffer.capacity()); System.out.println((char)buffer.get());
}
}
2.Buffer 缓冲区的更多相关文章
- Java NIO Buffer缓冲区
原文链接:http://tutorials.jenkov.com/java-nio/buffers.html Java NIO Buffers用于和NIO Channel交互.正如你已经知道的,我们从 ...
- Nio再学习之NIO的buffer缓冲区
1. 缓冲区(Buffer): 介绍 我们知道在BIO(Block IO)中其是使用的流的形式进行读取,可以将数据直接写入或者将数据直接读取到Stream对象中,但是在NIO中所有的数据都是使用的换冲 ...
- Netty buffer缓冲区ByteBuf
Netty buffer缓冲区ByteBuf byte 作为网络传输的基本单位,因此数据在网络中进行传输时需要将数据转换成byte进行传输.netty提供了专门的缓冲区byte生成api ByteBu ...
- Java NIO 之 Buffer(缓冲区)
一 Buffer(缓冲区)介绍 Java NIO Buffers用于和NIO Channel交互. 我们从Channel中读取数据到buffers里,从Buffer把数据写入到Channels. Bu ...
- 笔记:Node.js 的 Buffer 缓冲区
笔记:Node.js 的 Buffer 缓冲区 node.js 6.0 之前创建的 Buffer 对象使用 new Buffer() 构造函数来创建对象实例,但权限很大,可以获得敏感信息,所以建议使用 ...
- NIO(一):Buffer缓冲区
一.NIO与IO: IO: 一般泛指进行input/output操作(读写操作),Java IO其核心是字符流(inputstream/outputstream)和字节流(reader/writer ...
- C++ buffer缓冲区的秘密
在搞数据库和C++进行连接的时候,遇到一个问题,就是如果前面用到了fflush(stdin)即清空缓冲区,就OK,如果不清空缓冲区就不能把记录加入到Mysql的数据库中, 但是即便如此,这个问题目前还 ...
- Node.js Buffer(缓冲区)
JavaScript 语言自身只有字符串数据类型,没有二进制数据类型. 但在处理像TCP流或文件流时,必须使用到二进制数据.因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门 ...
- node(3)Buffer缓冲区
buffer 专门用来存放二进制数据的缓冲区:处理文件流 TCP流 const buf = Buffer.from('runoob', 'ascii'); // 创建一个长度为 10.且用 0x1 填 ...
- Nginx - buffer缓冲区部分
目录- 1. 前言- 2. 指令- 3. 原理及总结 1. 前言 关于缓冲,主要是合理设置缓冲区大小,尽量避免缓冲到硬盘 2. 指令 proxy_buffering 说明:proxy_bufferin ...
随机推荐
- java@ 注解原理与使用
Java反射 java反射机制的定义: 在运行转态时(动态的)时. 对于任意一个类,都能够知道这个类的所有属性和方法 对于任意一个对象,都能够知道调用它的任意属性和方法 Class对象 java中用对 ...
- java对list进行排序
主要讲述对list进行排序的几种方式 1.先来个简单的,上代码 import java.util.ArrayList; import java.util.Collections; import jav ...
- laravel输出HTML内容
blade模板引擎中的{{ $xxx }}表达式的返回值将被自动传递给 PHP 的 htmlentities 函数进行处理,以防止 XSS 攻击. 如果需要展示未转义的数据,可以使用{!! $xxx ...
- PHP重建数组的索引
sort() array_merge()跟一个空数组合并都可以重建索引数组的键(key)
- NET-使用Js调用WebService
注:JsWebServiceObject 此类是我做测试示例时为了测试js是否能调用webService中的复合类型而单独新建的一个类 此类中只有名字与年龄的属性. 最近身边的一个朋友做项目,其中有一 ...
- 汉化Git Gui
先来一个图: 其实使用自带的图形化操作git还是很方便的,但是英文界面还是让相当一部分小伙伴不太舒服,比如我哈. 汉化包地址:链接: https://pan.baidu.com/s/1qQtBUsf1 ...
- C#6.0-8.0新功能、ValueTuple
C# 6.0: https://www.cnblogs.com/yinrq/p/5600530.html C# 7.0: https://www.cnblogs.com/cncc/p/7698543. ...
- 线程.Qt更新界面
1.信号&槽 机制 即可 ZC:个人暂时 测试下来,类似是 PostMessage(...)的方式: a.是在各自的线程中执行代码, b.调用 emit不耗时(指的意思是 像调用PostMes ...
- Nginx基本使用方法
原帖:http://zyjustin9.iteye.com/blog/2017394 相信很多人都听过nginx,这个小巧的东西慢慢地在吞食apache和IIS的份额.那究竟它有什么作用呢?可能很多人 ...
- solr新建core