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. MyBatis的几个重要概念和工作流程

    MyBatis 几个重要的概念 Mapper 配置: Mapper 配置可以使用基于 XML 的 Mapper 配置文件来实现,也可以使用基于 Java 注解的 MyBatis 注解来实现,甚至可以直 ...

  2. 学习笔记66_DBSCAN聚类算法

  3. 命令行代理神器 proxychains

    因为某些原因,我们需要在命令行下载一些国外的资源,这个时候如果使用 wget,curl,或者 aria2c 的时候,往往又没有速度.这个时候我们需要使用代理来进行加速. 我本地搭的有 ss,但 ss ...

  4. 网络安全-主动信息收集篇第二章-三层网络发现之nmap和fping和Hping

    nmap IP  -sn nmap当目标IP在同一网段时,nmap会发送ARP包,当目标IP不在同一网段时nmap会发送ICMP的包. fping IP fping  -g 参数支持对IP地址起始和结 ...

  5. [07/18NOIP模拟测试5]超级树

    鬼能想到的dp定义:dp[i][j]表示在一棵i级超级树中,有j条路径同时存在且这j条路径没有公共点时,可能的情况数 刚开始我也没看懂,所以举个例子 如一个2级的超级树,父节点为1,左右儿子为2,3 ...

  6. 原生JS实现二叉搜索树(Binary Search Tree)

    1.简述 二叉搜索树树(Binary Search Tree),它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的右子树不空,则右子 ...

  7. NOIp2017 列队(线段树)

    嘛..两年前的题目了,想起第一次参加提高组还骗了一个省二回来呢...跟同学吹了好久的... 离退役又近了一骗博客啊.. 闲聊结束. 照常化简:给定一个1-n*m编号的矩阵,每次删除一个位置,然后左边向 ...

  8. 爬虫学习--Day3(小猿圈爬虫开发_1)

    爬虫基础简介 前戏: 1.你是否在夜深人静的时候,想看一些让你更睡不着的图片 2.你是否在考试或者面试前夕,想看一些具有针对性的题目和面试题 3.你是否想在杂乱的网络世界中获取你想要的数据 什么是爬虫 ...

  9. Nginx 的进程结构,你明白吗?

    Nginx 进程结构 这篇文章我们来看下 Nginx 的进程结构,Nginx 其实有两种进程结构: 单进程结构 多进程结构 单进程结构实际上不适用于生产环境,只适合我们做开发调试使用.因为在生产环境中 ...

  10. 学习笔记之vim的使用

    很多刚学习linux编程的人总是对vim有一种恐惧,我自己就是这么回事的. 可是当你努力的去尝试学习使用后,才发现它的精髓所在. 在我看来,让vim变得好用的前提是要安装两个插件,ctags和tagl ...