NIO大三组件 之Buffer

一、什么是Buffer

Buffer是用于特定原始类型的数据的容器。 它的实质就是一组数组,用于存储不同类型的数据。

二、缓冲区的类型

缓冲区类型除了Boolean值类型外,其余基本类型都含有。

NIO中定义的抽象缓冲区对象如下(均继承至Buffer抽象类):

  • ByteBuffer
  • CharBuffer
  • ShortBuffer
  • IntBuffer
  • LongBuffer
  • FloatBuffer
  • DoubleBuffer

上述类均为抽象类,它们的实现还分有直接缓冲区和非直接缓冲区。

三、缓冲区中的四个核心属性

  • category: 容量,表示缓冲区的大小,一旦声明就不可改变。
  • limit: 界限,表示缓冲区中可以操作数据的大小。(llimit后面的数据不可读写)
  • position: 位置,表示缓冲区中正在操作数据的位置。
  • mark: 标记,可以标记当前position的位置。

写操作

进行写操作时,limit=category,limit表示的是可以写的地址范围。

position则表示当前写的索引,每写一个字节position则+1。

读操作

进行读操作时,limit=position,limit此时则表示可读取的范围,此时范围则会被赋值为写的position

而当position赋值完给limit后,position则置零。在读操作中position则表示读的索引。

它们之间的关系

mark <= position <= limit <= capacity

@Test
public void markTest(){
String str = "abcde"; ByteBuffer buf = ByteBuffer.allocate(1024);
byte[] bytes = new byte[10];
buf.put(str.getBytes()); //切换到读模式
buf.flip();
//获取buf的两个字节
buf.get(bytes, 0, 2);
System.out.println(new String(bytes)); //标记position的位置
buf.mark();
//获取buf的两个字节
buf.get(bytes, 2, 2);
System.out.println(new String(bytes));
System.out.println(buf.position());
//回到position=2的位置
buf.reset(); System.out.println(buf.position());
}

四、存取缓冲区数据的核心方法

  • put():存入数据到缓冲区中
  • get(): 获取缓冲区中的数据
  • flip(): 读写切换
  • clear():清空写缓存,,只是把position和limit重置为最初状态,但是缓存区的内容并没有删除
  • mark(): 保存当前position的位置
  • reset(): 把当前的position重置为mark的值
  • rewind(): 重读操作,position置0
    @Test
public void bufferMethodTest(){
String str = "abcde"; //声明一个Byte缓冲区(非直接缓冲区),并设置缓冲区大小为1024
ByteBuffer buf = ByteBuffer.allocate(1024);
//直接缓冲区申请方式
//ByteBuffer.allocateDirect(1024);
System.out.println("-------------------------allocate------------------------");
//0
System.out.println(buf.position());
//1024
System.out.println(buf.limit());
//1024
System.out.println(buf.capacity()); System.out.println("-------------------------put------------------------");
//把str的数据放入缓冲区
buf.put(str.getBytes());
//5
System.out.println(buf.position());
//1024
System.out.println(buf.limit());
//1024
System.out.println(buf.capacity()); //3.切换读取数据模式
buf.flip();
System.out.println("-------------------------get------------------------");
byte[] bytes = new byte[20];
//读取缓冲区理的5个字节
buf.get(bytes,0, buf.limit());
//5,表示数据读到的位置
System.out.println(buf.position());
//5.表示可以读的位置
System.out.println(buf.limit());
System.out.println(buf.capacity()); //5. rewind: 可重读
buf.rewind();
System.out.println("-------------------------rewind------------------------");
//position回到0
System.out.println(buf.position());
//5.表示可以读的位置,5
System.out.println(buf.limit());
System.out.println(buf.capacity()); //clear(): 清空缓存区,但数据任然存在,只是把position和limit重置为最初状态。
buf.clear();
System.out.println("-------------------------clear------------------------");
//postion变为0
System.out.println(buf.position());
//1024
System.out.println(buf.limit());
System.out.println(buf.capacity());
}

五、补充

关于直接缓冲区与非直接缓冲区

  • 直接缓冲区: 缓冲区地址直接映射到磁盘地址。
  • 非直接缓冲区: 缓冲区地址先通过JVM缓存,然后再由JVM向OS申请内存空间。(实质是堆)
两种方式的优缺点
  1. 非直接缓冲区有JVM到OS这段中间开销,使得访问性能下降。但是由于缓存在JVM堆中,数据受程序控制。
  2. 直接缓冲区没有中间开销,但由于内存是向OS申请,缓冲区的数据存储不受程序的控制。



Java NIO 三大组件之 Buffer的更多相关文章

  1. 第一章 java nio三大组件与使用姿势

    本案例来源于<netty权威指南> 一.三大组件 Selector:多路复用器.轮询注册在其上的Channel,当发现某个或者多个Channel处于“就绪状态”后(accept接收连接事件 ...

  2. NIO三大组件之Buffer

    什么是Buffer Buffer(这里并不是特指Buffer类)是一个存储数据的容器,与数组类似(其实底层依旧是用数组的结构来存储数据),但不同的是,Buffer对象提供了一组更有效的方法去进行写入和 ...

  3. Java NIO 三大组件之 Channel

    Java NIO 之 Channel 一.什么是Channel Channel用于源节点(例如磁盘)与目的节点的连接,它可以进行读取,写入,映射和读/写文件等操作. 在Java NIO中负责缓冲区中数 ...

  4. java web(五):java web三大组件之另外两个和八大监听器

    java的三大组件指Servlet.Filter.Listener.八大监听器指八个接口.前面介绍了Servlet,现在介绍一下Filter拦截器以及拦截地址的设置, Listener监听那些事件. ...

  5. NIO三大组件简介

    NIO简介 NIO 是面向缓冲区(或者说面向块)编程的, 因为Buffer底层本质上就是内存块.数据被读取到一个缓冲区, 稍后再被它处理, 需要时数据可在缓冲区前后移动, 从而增加了处理过程中的灵活性 ...

  6. 转:Java NIO系列教程(三) Buffer

    Java NIO中的Buffer用于和NIO通道进行交互.如你所知,数据是从通道读入缓冲区,从缓冲区写入到通道中的. 缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这块内存被包装成NIO ...

  7. java nio(一)buffer

    概述 常见的网络io分为两种情况,BIO(block-io)和NIO(non-block-io),分别位于java.io和java.nio. BIO,是阻塞的io,采用一个线程处理一个连接的方式,就算 ...

  8. java web 三大组件

    JavaWeb三大组件 Servlet,Filter,Listener. Servlet Servlet的作用 在Java web b/s架构中,servlet扮演了重要的角色,作为一个中转处理的容器 ...

  9. Java NIO中的缓冲区Buffer(二)创建/复制缓冲区

    创建缓冲区的方式 主要有以下两种方式创建缓冲区: 1.调用allocate方法 2.调用wrap方法 我们将以charBuffer为例,阐述各个方法的含义: allocate方法创建缓冲区 调用all ...

随机推荐

  1. ubuntu18.04 flink-1.9.0 Standalone集群搭建

    集群规划 Master JobManager Standby JobManager Task Manager Zookeeper flink01 √ √ flink02 √ √ flink03 √ √ ...

  2. bit(比特)与Byte(字节)的区别与关系

    1.bit:位 (小写b) 也称比特 是英文 binary digit的缩写 二进制数系统中,每个0或1就是一个位(bit)位是数据存储(计算机中信息)的最小单位计算机中的CPU位数指的是CPU一次能 ...

  3. 讲一讲快速学习WPF的思路

    我不想浪费大家的时间,直接奔主题了. 首先大家要明白,WPF跟Winform的区别,优点,缺点. 首先入门来讲 Winform简单点,WPF会难一点.所以第一次接触C# 我推荐用Winform项目去学 ...

  4. [知识图谱]Neo4j知识图谱构建(neo4j-python-pandas-py2neo-v3)

    neo4j-python-pandas-py2neo-v3 利用pandas将excel中数据抽取,以三元组形式加载到neo4j数据库中构建相关知识图谱 Neo4j知识图谱构建 1.运行环境: pyt ...

  5. Linux下Redis安装与配置

    http://www.cnblogs.com/_popc/p/3684835.html

  6. js中关于执行的顺序及变量存放方式的一点记录

    Markdown在线编辑器 - www.MdEditor.com 1 首先关于数据类型,有基本数据类型,和引用数据类型 基本数据类型有:number,string,boolean等:引用数据类型一般指 ...

  7. 通过ISO镜像简单搭建本地yum仓库

    本文参考链接:https://segmentfault.com/a/1190000015155966 *有时候在我们本地搭建一些Linux上的程序运行环境或者安装一些软件的时候,难免会遇到需要使用yu ...

  8. java应用性能调优之详解System的gc垃圾回收方法

    一.什么是System.gc()? System.gc()是用Java,C#和许多其他流行的高级编程语言提供的API.当它被调用时,它将尽最大努力从内存中清除垃圾(即未被引用的对象).名词解释:GC, ...

  9. 底半部之工作队列和tasklet,内核定时器。

    1.软中断机制  不能以模块形式出现   使用起来不够灵活2.tasklet  核心数据结构       struct tasklet_struct      {          function  ...

  10. Scrapy进阶知识点总结(四)——Item Pipeline

    Item Pipeline Item Pipeline调用发生在Spider产生Item之后.当Spider解析完Response之后,Item就会传递到Item Pipeline,被定义的Item ...