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.基本上失去了对缓冲区数据的控制,无法控制其销毁

所以:仅在直接缓冲区能在程序性能方面带来明显好处时分配他们

  1 /*
  2  * 一、缓冲区(Buffer):在Java NIO中负责数据的存取。缓冲区就是数组。用于存储不同数据类型的数据
  3  *
  4  * 根据数据类型不同 (boolean 除外),提供了相应类型的缓冲区
  5  * ByteBuffer(常用) 、CharBuffer、ShortBuffer等
  6  *
  7  * 上述缓冲区 的 管理方式几乎一致,通过 allocate() 获取缓冲区
  8  *
  9  * 二、缓冲区存取数据的两个核心方法:
 10  * put():存入 数据到缓冲区
 11  * get():获取缓冲区的数据
 12  *
 13  * 三、缓冲区的四个核心属性
 14  * 1.capacity : 容量,表示Buffer 最大数据容量,缓冲区容量不能为负,并且创建后不能修改  (创建Buffer对象时 初始化)
 15  *
 16  * 2.限制(limit):第一个不应该读取或写入的数据的索引,(即位于limit后的数据不可读写)
 17                              缓冲区的限制 不能为负,并且不能大于其容量
 18    3.位置(position):下一个要读取或写入的数据的索引。缓冲区的位置不能为负,并且不能大于其限制值
 19
 20    4.标记(mark)与重置(reset):标记也是一个索引,通过Buffer中的 mark() 方法指定Buffer中一个特定的position,
 21         之后可以通过调用reset()方法恢复到这个 position
 22  *
 23  *  0 <= mark <= position <= limit <= capacity
 24  *
 25  *  四、直接缓冲区 和 非直接缓冲区
 26  *  非直接缓冲区:通过allocate() 方法 分配缓冲区,将采取建立在 JVM内存中
 27  *  直接缓冲区:通过 allocateDirect() 方法 分配直接缓冲区,将缓冲区建立在物理内存中,可以提高效率
 28  *
 29  * */
 30
 31 public class TestBuffer {
 32
 33     @Test
 34     public void test3() {
 35         ByteBuffer buffer1 = ByteBuffer.allocateDirect(1024);
 36         System.out.println(buffer1.isDirect());
 37         ByteBuffer buffer2 = ByteBuffer.allocate(1024);
 38         System.out.println(buffer2.isDirect());
 39     }
 40
 41     @Test
 42     public void test2() {
 43         String str = "abcd";
 44         ByteBuffer buffer = ByteBuffer.allocate(1024);
 45
 46         buffer.put(str.getBytes());
 47
 48         buffer.flip();
 49
 50         byte[] bytes = new byte[buffer.limit()];
 51         buffer.get(bytes,0,2);
 52
 53         //position = 2
 54         System.out.println(new String(bytes));
 55         System.out.println(buffer.position());
 56
 57         //标记当前 position
 58         buffer.mark();
 59
 60         //position = 4
 61         buffer.get(bytes,2,2);
 62         System.out.println(new String(bytes));
 63         System.out.println(buffer.position());
 64
 65         //将 position reset 到 标记的位置  position = 2
 66         buffer.reset();
 67         System.out.println(buffer.position());
 68     }
 69
 70     @Test
 71     public void test1() {
 72         //1.分配一个指定大小的缓冲区
 73         ByteBuffer buffer = ByteBuffer.allocate(1024);
 74         System.out.println("-------------allocate()-------------");
 75         System.out.println(buffer.position());
 76         System.out.println(buffer.limit());
 77         System.out.println(buffer.capacity());
 78
 79         //2.利用 put() 存入数据到缓冲区
 80         String str = "abcedf";
 81         buffer.put(str.getBytes());
 82         System.out.println("-------------put()-------------");
 83         System.out.println(buffer.position());     //此时 位置 索引会变成6,即下一个要读取或写入的数据的索引 是 6 (byte[6])
 84         System.out.println(buffer.limit());
 85         System.out.println(buffer.capacity());
 86
 87         //3.使用 get() 读取数据之前,需要调用 flip() 方法,切换到 读取数据模式 (将position置为0,limit置为原先position)
 88         //不然按照现在的所以 是无法读取到任何数据的
 89         buffer.flip();
 90         System.out.println("-------------flip()-------------");
 91         System.out.println(buffer.position());
 92         System.out.println(buffer.limit());
 93         System.out.println(buffer.capacity());
 94
 95         //4.利用 get() 读取缓冲区中的数据
 96         //读取 需要创建一个容器去装
 97         byte[] bytes = new byte[buffer.limit()];
 98         //将读取到的数据 放到 这个 byte数组中
 99         buffer.get(bytes);
100
101         System.out.println("-------------get()-------------");
102         System.out.println(buffer.position());
103         System.out.println(buffer.limit());
104         System.out.println(buffer.capacity());
105         System.out.println(new String(bytes,0,bytes.length));
106
107         //5.rewind() 可重复读  将位置设成 0 ,取消设置的 remark,现在就可以重新读取了
108         buffer.rewind();
109         System.out.println("-------------rewind()-------------");
110         System.out.println(buffer.position());
111         System.out.println(buffer.limit());
112         System.out.println(buffer.capacity());
113
114         //6.clear()  清空缓存区,缓冲区中的数据依然存在,但是 处于 ‘被遗忘’状态
115         buffer.clear();
116         System.out.println("-------------clear()-------------");
117         System.out.println(buffer.position());
118         System.out.println(buffer.limit());
119         System.out.println(buffer.capacity());
120
121         System.out.println((char)buffer.get());
122     }
123 }
时间: 2024-10-10 02:46:48

2.Buffer 缓冲区的相关文章

笔记:Node.js 的 Buffer 缓冲区

笔记:Node.js 的 Buffer 缓冲区 node.js 6.0 之前创建的 Buffer 对象使用 new Buffer() 构造函数来创建对象实例,但权限很大,可以获得敏感信息,所以建议使用 buffer.from() 接口创建 Buffer 对象. Buffer 实例要以通过显式字符编码与普通的字符串之间进行相互转换,支持 assii,utf8,utf16le,ucs2-utf16le,base64,latin1,binary-latin1,hex. 写稿缓冲区(buf.write)

【node.js】Buffer(缓冲区)

Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区. 创建 Buffer 类 Node Buffer 类可以通过多种方式来创建. 1.创建长度为 10 字节的 Buffer 实例: var buf = new Buffer(10); 2.通过给定的数组创建 Buffer 实例: var buf = new Buffer([10, 20, 30, 40, 50]); 3.通过一个字符串来创建 Buffer 实例: var buf = new Buffer("

nodejs基础 -- buffer缓冲区

JavaScript 语言自身只有字符串数据类型,没有二进制数据类型.但在处理像TCP流或文件流时,必须使用到二进制数据.因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区.在 Node.js 中,Buffer 类是随 Node 内核一起发布的核心库.Buffer 库为 Node.js 带来了一种存储原始数据的方法,可以让 Node.js 处理二进制数据,每当需要在Node.js 中处理I/O操作中移动的数据时,就有可能使用 Buffer 库.原始

Node.js Buffer(缓冲区)

JavaScript 语言自身只有字符串数据类型,没有二进制数据类型. 但在处理像TCP流或文件流时,必须使用到二进制数据.因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区. 在 Node.js 中,Buffer 类是随 Node 内核一起发布的核心库.Buffer 库为 Node.js 带来了一种存储原始数据的方法,可以让 Node.js 处理二进制数据,每当需要在 Node.js 中处理I/O操作中移动的数据时,就有可能使用 Buffer 库

Nginx - buffer缓冲区部分

目录- 1. 前言- 2. 指令- 3. 原理及总结 1. 前言 关于缓冲,主要是合理设置缓冲区大小,尽量避免缓冲到硬盘 2. 指令 proxy_buffering 说明:proxy_buffering这个参数用来控制是否打开后端响应内容的缓冲区,如果这个设置为off,那么proxy_buffers和proxy_busy_buffers_size这两个指令将会失效.但是无论proxy_buffering是否开启,对proxy_buffer_size都是生效的. proxy_buffering开启

NIO:同步异步和阻塞非阻塞 buffer缓冲区

NIO的引入 多路非阻塞高速网络IO通道 同步和异步 这个概念其是对于程序运行结果的获得方式而言: 同步:在没有获得结果之前或通过轮询的方式不断地询问结果是否产生,在得到结果之前不会返回 异步:调用者在发出调用之后,直接返回没有结果,等待被调用者产生结果之后通过状态通知调用者已完成,在通过回调函数返回结果 阻塞和非阻塞 阻塞:在执行进程时,在没有得到结果之前,这个进程暂时被挂起,不进行任何操作 非阻塞:在没有得到结果之前,该线程不会停止操作,即不会阻塞当前线程; Buffer类(缓冲区) 概念:

None.js 第五步 Buffer(缓冲区)

// 存数据,取数据; buf = Buffer.alloc(26); for (var i = 0; i < 26; i++) { buf[i] = i + 97; } console.log(buf.toString('ascii')); console.log(buf.toString('ascii',0,5)); console.log(buf.toString('utf8',0,5)); console.log(buf.toString(undefined, 0, 5)); 输出 ab

Linux文件系统(五)---三大缓冲区之buffer块缓冲区

在文件系统中,有三大缓冲为了提升效率:inode缓冲区.dentry缓冲区.块缓冲. (内核:2.4.37) 二.块buffer缓冲区 0.整体来说,Linux 文件缓冲区分为page cache和buffer cache,每一个 page cache 包含若干 buffer cache. > 内存管理系统和 VFS 只与 page cache 交互,内存管理系统负责维护每项 page cache 的分配和回收,同时在使用"内存映射"方式访问时负责建立映射. > VFS 负

缓冲区Buffer和缓存区Cache的区别

1.buffer 将数据写入到内存里,这个数据的内存空间在Linux系统里一般被称为缓冲区(buffer),例如:写入到内存buffer缓冲区,即写缓冲. 为了提高写操作性能,数据在写入最终介质或下一层级介质前会合并放在缓冲区中.这样会增加数据持久写的延时,因为第一次写入缓冲区后,在向下写入数据之前,还要等后续写入,以便凑够数据或者定时写入到永久存储介质中. 2.cache 从内存里读取数据,这个存数据的内存空间在Linux系统里一般称为缓存区(cache),例如:从内存cache读取,即读缓存