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. jquery复习

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. Scrapy 之settings配置

    BOT_NAME 默认: 'scrapybot' 当您使用 startproject 命令创建项目时其也被自动赋值. ROBOTSTXT_OBEY = False 是否遵守rebotes.txt协议 ...

  3. Android H5混合开发(5):封装Cordova View, 让Fragment、弹框、Activity自由使用Cordova

    近期,有同事咨询如何在Fragment中使用Cordova,看了下Cordova源码,官方并没有提供包含Cordova Webview的Fragment,以供我们继承. 上网查询了一下,也有几篇文章讲 ...

  4. mock和axios常见的传参方式

    第一次接手项目,传参方式还有些吃力,因此做一下总结. 首先我们需要会看swagger中的接口.里面写了某个接口需要接收什么样的值,前端怎么传递这个值 在mock中的传参方式: mock中传参的方式有两 ...

  5. 程序员接私活经验总结,来自csdn论坛语录

    以下为网上摘录,以做笔记: 可是到网上看看,似乎接私活也有很多不容易,技术问题本身是个因素,还有很多有技术的人接私活时被骗,或者是合作到最后以失败告终,所以想请有经验的大侠们出来指点一下,接私活是怎么 ...

  6. 在线热备份数据库之innobackupex 增量备份InnoDB

    在线热备份数据库之innobackupex 增量备份InnoDB 什么是增量备份?其原理是什么? 增量备份是基于上一次备份后对新增加的内容进行备份,优点相较于完整备份而言备份内容少时间短,能够节省磁盘 ...

  7. NOIP模拟27(命悬一线)

    考得太悬了!

  8. 开发板,pc,虚拟机三者如何互相ping通

    1 安装虚拟机时,主机和虚拟机必须是桥接网卡,保证了ip 同一:192,168,1,xx 2 打开虚拟机之前,先把pc机的无线网卡禁用掉只能使用本地连接,pc通过网线连接上网,打开虚拟机,命令行输入: ...

  9. linux 安装swoole扩展方法

    linux 安装swoole扩展方法 wget https://github.com/swoole/swoole-src/archive/v1.9.23.tar.gz接下去就不说了 说明下 下载swo ...

  10. IP网段的判断

    一.    OSI七层模型 表示 说明 作用 应用层 HTTP.ftp 协议 表示层 UTF-8 将应用层协议翻译成计算机可识别的语言 会话层 管理传输层 传输层 TCP/UDP 建立以及断开连接 网 ...