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. index.html

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  2. deepin15.5 安装tensorflow-gpu

    deepin的CUDA和cuDNN安装方法与其它系统有所不同,参考其它操作系统的方法也许不适用,特别是显卡驱动的安装,容易使系统出现问题 本次配置: 操作系统:deepin15.5桌面版 电脑品牌:联 ...

  3. git从远程仓库拉取内容或向远程仓库上传内容

    一.将本地文件上传到远程仓库步骤 git init git add . git commit -m "初始框架" git remote add origin https://git ...

  4. 务必收藏备用:.net core中通过Json或直接获取图形验证码(数字验证码、字母验证码、混合验证码),有源代码全实战demo(开源代码.net core3.0)

    很多人写的博客大家看了会一知半解,不知道怎么用,应该引用什么类库或者代码不全,这样很多小白很是头疼,尤其是尝新技术更是如此.我们这边不止告诉你步骤,而且还提供开源demo.随着时间的推移,我们的dem ...

  5. 解决SAP740 GUI 搜索帮助(F4)回填值乱码的问题

    SAP 740客户端引入了搜索帮助增强功能,并且默认是开启该功能的,在带有F4搜索帮助的字段输入框中输入字段的前两个字符,可以自动以下拉框的方式带出包含包含所输入字符的条目,从而实现快速的输入帮助,如 ...

  6. 调用微信js sdk

    场景:需要调用微信获取当前位置的借口. 途径:查看微信 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115 .后 ...

  7. Android 这 13 道 ContentProvider 面试题,你都会了吗?

    前言 作为 Android 的四大组件之一,ContentProvider 可以说是无处不在了. 但是对于我而言,开发过程中看似 ContentProvider 用得很娴熟,却一直没能形成一个完整的体 ...

  8. 测试工程师,选择python还是java?

    问:“你平时工作中,用java多还是用python多”? 答:“都还可以,根据具体的场景选择不同的语言”. 问:“比如说呢”? 答:“开发自己的测试平台,肯定会选择java:在centos服务器跑一些 ...

  9. windows使用docker运行mysql等工具(二)安装运行mysql

    今天接着上一篇的内容继续来学习安装运行mysql.建议先阅读第一篇:windows安装docker 一 查看mysql版本 如果想知道mysql镜像具体有哪几个版本,需要去docker hub查看. ...

  10. Fiddler 原理及iPhone的配置

    原理: 首先Fiddler运行在自己的PC上,Fiddler运行的时候会在PC的8888端口开启一个代理服务,这个服务实际上是一个HTTP/HTTPS的代理. 确保手机和PC在同一个局域网内,我们可以 ...