/*缓冲区(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. }

2.Buffer 缓冲区的更多相关文章

  1. Java NIO Buffer缓冲区

    原文链接:http://tutorials.jenkov.com/java-nio/buffers.html Java NIO Buffers用于和NIO Channel交互.正如你已经知道的,我们从 ...

  2. Nio再学习之NIO的buffer缓冲区

    1. 缓冲区(Buffer): 介绍 我们知道在BIO(Block IO)中其是使用的流的形式进行读取,可以将数据直接写入或者将数据直接读取到Stream对象中,但是在NIO中所有的数据都是使用的换冲 ...

  3. Netty buffer缓冲区ByteBuf

    Netty buffer缓冲区ByteBuf byte 作为网络传输的基本单位,因此数据在网络中进行传输时需要将数据转换成byte进行传输.netty提供了专门的缓冲区byte生成api ByteBu ...

  4. Java NIO 之 Buffer(缓冲区)

    一 Buffer(缓冲区)介绍 Java NIO Buffers用于和NIO Channel交互. 我们从Channel中读取数据到buffers里,从Buffer把数据写入到Channels. Bu ...

  5. 笔记:Node.js 的 Buffer 缓冲区

    笔记:Node.js 的 Buffer 缓冲区 node.js 6.0 之前创建的 Buffer 对象使用 new Buffer() 构造函数来创建对象实例,但权限很大,可以获得敏感信息,所以建议使用 ...

  6. NIO(一):Buffer缓冲区

    一.NIO与IO: IO:  一般泛指进行input/output操作(读写操作),Java IO其核心是字符流(inputstream/outputstream)和字节流(reader/writer ...

  7. C++ buffer缓冲区的秘密

    在搞数据库和C++进行连接的时候,遇到一个问题,就是如果前面用到了fflush(stdin)即清空缓冲区,就OK,如果不清空缓冲区就不能把记录加入到Mysql的数据库中, 但是即便如此,这个问题目前还 ...

  8. Node.js Buffer(缓冲区)

    JavaScript 语言自身只有字符串数据类型,没有二进制数据类型. 但在处理像TCP流或文件流时,必须使用到二进制数据.因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门 ...

  9. node(3)Buffer缓冲区

    buffer 专门用来存放二进制数据的缓冲区:处理文件流 TCP流 const buf = Buffer.from('runoob', 'ascii'); // 创建一个长度为 10.且用 0x1 填 ...

  10. Nginx - buffer缓冲区部分

    目录- 1. 前言- 2. 指令- 3. 原理及总结 1. 前言 关于缓冲,主要是合理设置缓冲区大小,尽量避免缓冲到硬盘 2. 指令 proxy_buffering 说明:proxy_bufferin ...

随机推荐

  1. HTTP和WSGI协议

    HTTP协议简介 超文本传输协议(HyperText Transfer Protocol)是一种应用层协议.HTTP是万维网的数据通信的基础.设计HTTP最初的目的是为了提供一种发布和接收HTML页面 ...

  2. 实例解析Python设计模式编程之桥接模式的运用

    实例解析Python设计模式编程之桥接模式的运用 这篇文章主要介绍了Python设计模式编程之桥接模式的运用,桥接模式主张把抽象部分与它的实现部分分离,需要的朋友可以参考下 我们先来看一个例子: #e ...

  3. Hive之insert into与insert overwrite区别

    一.实践先行,直接上手 1. hive 表及数据准备 建表,并插入初始数据.向表中插入 hive> use test; hive> create table kwang_test (id ...

  4. springboot-mybatis-pagehelper(分页插件)

    依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://m ...

  5. 【C# 开发技巧】 Application.DoEvents( ) 使用笔记

    该方法可以处理当前队列的消息,比如一个for循环 5000次 向TextBox中追加文本,那肯定会假死一会儿的. 此时便可使用Application.DoEvents()来处理队列的信息. 简单说下使 ...

  6. boost::bind四种应用场景的例子

        普通函数 int f( int a, int b ){return a + b;}boost::bind( f, _1, 9 )( 1 ) 成员函数 struct demo{int f( in ...

  7. RAID(独立磁盘冗余阵列)

    Raid ​ RAID 独立磁盘冗余阵列,在本科学习时候学习过,记不清是组成原理还是操作系统,当时理解的不太清楚,现在研究生期间做存储相关项目,涉及到了Raid,于是查各种博客,为了以后便于后期查阅, ...

  8. v-bind 绑定属性

    与mustache相区别,他是对内容(content内部)进行修改的.v-bind的语法糖写法是   : v-bind 动态绑定class属性:v-bind:class="对象名" ...

  9. 微信公众号对接JS-SDK接口 调用微信内置地图

    微信js-sdk开发文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html 1.页面配置 引用微信js- ...

  10. 通过js操作,将div设置为contenteditable的内容设为全选状态

    因为div设置为contenteitable可编辑的文本内容用 select()选择全部内容不生效,所以只能用下列方法: 先 creatTextRange或者 createRange <div ...