概念讲解,转自https://www.cnblogs.com/lxzh/archive/2013/05/10/3071680.html  ,将的非常好!

Buffer 类是 java.nio 的构造基础。一个 Buffer 对象是固定数量的数据的容器,其作用是一个存储器,或者分段运输区,在这里,数据可被存储并在之后用于检索。缓冲区可以被写满或释放。对于每个非布尔原始数据类型都有一个缓冲区类,即 Buffer 的子类有:ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer 和 ShortBuffer,是没有 BooleanBuffer 之说的。尽管缓冲区作用于它们存储的原始数据类型,但缓冲区十分倾向于处理字节。非字节缓冲区可以在后台执行从字节或到字节的转换,这取决于缓冲区是如何创建的。 
◇ 缓冲区的四个属性 
        所有的缓冲区都具有四个属性来提供关于其所包含的数据元素的信息,这四个属性尽管简单,但其至关重要,需熟记于心:

  • 容量(Capacity):缓冲区能够容纳的数据元素的最大数量。这一容量在缓冲区创建时被设定,并且永远不能被改变。
  • 上界(Limit):缓冲区的第一个不能被读或写的元素。缓冲创建时,limit 的值等于 capacity 的值。假设 capacity = 1024,我们在程序中设置了 limit = 512,说明,Buffer 的容量为 1024,但是从 512 之后既不能读也不能写,因此可以理解成,Buffer 的实际可用大小为 512。
  • 位置(Position):下一个要被读或写的元素的索引。位置会自动由相应的 get() 和 put() 函数更新。 这里需要注意的是positon的位置是从0开始的。
  • 标记(Mark):一个备忘位置。标记在设定前是未定义的(undefined)。使用场景是,假设缓冲区中有 10 个元素,position 目前的位置为 2(也就是如果get的话是第三个元素),现在只想发送 6 - 10 之间的缓冲数据,此时我们可以 buffer.mark(buffer.position()),即把当前的 position 记入 mark 中,然后 buffer.postion(6),此时发送给 channel 的数据就是 6 - 10 的数据。发送完后,我们可以调用 buffer.reset() 使得 position = mark,因此这里的 mark 只是用于临时记录一下位置用的。

请切记,在使用 Buffer 时,我们实际操作的就是这四个属性的值。我们发现,Buffer 类并没有包括 get() 或 put() 函数。但是,每一个Buffer 的子类都有这两个函数,但它们所采用的参数类型,以及它们返回的数据类型,对每个子类来说都是唯一的,所以它们不能在顶层 Buffer 类中被抽象地声明。它们的定义必须被特定类型的子类所遵从。若不加特殊说明,我们在下面讨论的一些内容,都是以 ByteBuffer 为例,当然,它当然有 get() 和 put() 方法了。

API使用

这里再贴一些常用APi的练习code

//nio中Buffer的使用
public class BufferTest { @Test
public void test01(){
IntBuffer buf=IntBuffer.allocate(10);//创建指定长度的缓冲buffer
//pos: 存储或者读取到的数据的当前位置,下一个数据将从该position处后面的一个字节开始存储
//limit:缓冲区中数据的有效位置,默认和容量一样
//cap:初始容量
System.out.println(buf);//[pos=0 lim=10 cap=10]
buf.put(1); //pos 加一 put(int)方法 pos会加一
buf.put(2); //pos 加一
buf.put(3); //pos 加一
System.out.println(buf);//[pos=3 lim=10 cap=10]
buf.flip();//复位,pos变为o,limit变为buffer中实际数量
System.out.println(buf);//[pos=0 lim=3 cap=10]
buf.put(1,0); // 向某一个明确已有数据位置put数据,pos不变
buf.get(2); //获取某个下标数据时,pso也不变
//注意: put或get 某个下标时,必须小于limit-1(下标从0开始),否则会抛异常
System.out.println(buf);//[pos=0 lim=3 cap=10]
//循环获取时,需要用limit,不能用容量
for (int i = 0; i < buf.limit(); i++) {
//调用get方法会使其缓冲区位置(position)向后递增一位
System.out.print(buf.get() + "\t");
}
System.out.println();
System.out.println("buf对象遍历之后为: " + buf);//[pos=3 lim=3 cap=10]
} @Test
public void test02(){
/**
* wrap方法会包裹一个数组: 一般这种用法不会先初始化缓存对象的长度,因为没有意义,
* 最后还会被wrap所包裹的数组覆盖掉。并且wrap方法修改缓冲区对象的时候,数组本身也会跟着发生变化。
*/
IntBuffer buf = IntBuffer.allocate(10);
int[] arr=new int[]{1,2,5};
buf = IntBuffer.wrap(arr);
System.out.println(buf);//[pos=0 lim=3 cap=3]
//添加数组的前两个数进入buffer,容量还是原来数组的容量
IntBuffer buf01 = IntBuffer.wrap(arr, 0, 2);
System.out.println(buf01);//[pos=0 lim=2 cap=3] IntBuffer buf3 = buf.duplicate();//克隆一个buffer
System.out.println(buf3);
//buf.position(0);//设置buffer的pos.一般不建议使用这个,都使用后flap
//最佳遍历方式
buf.remaining();//获取目前可读数据长度,即limit长度
int[] arr2 = new int[buf.remaining()];
//将缓冲区数据放入arr2数组中去
buf.get(arr2);
for(int i : arr2){
System.out.print(Integer.toString(i) + "\t");//1 2 5
}
}

  如果有其他兴趣可以去上面转载地址深入研究或者自己深入研究!

NIO编程中buffer对象的理解以及API的使用的更多相关文章

  1. Qt多线程编程中的对象线程与函数执行线程

    近来用Qt编写一段多线程的TcpSocket通信程序,被其中Qt中报的几个warning搞晕了,一会儿是说“Cannot create children for a parent that is in ...

  2. java-基础-【四】实际编程中的对象

    一.概述 实际编程开发中,仅仅一个数据库对象映射是满足不了各种复杂需求. O/R Mapping 是 Object Relational Mapping(对象关系映射)的缩写.通俗点讲,就是将对象与关 ...

  3. python核心编程中的对象值比较VS对象身份比较(转载)

    转载地址: https://blog.csdn.net/Mluka/article/details/51076786 在python核心编程第四章中,P69在优化下面这段代码时提出了:对象值比较VS对 ...

  4. 在js中arguments对象的理解

    一.在函数调用的时候,浏览器每次都会传递进两个隐式参数 函数的上下文对象this 封装实参的对象arguments 二.arguments 对象 arguments 对象实际上是所在函数的一个内置类数 ...

  5. C++编程中对缓冲区的理解(OS默认4096大小的缓冲区,有例子,很形象)

    什么是缓冲区缓冲区又称为缓存,它是内存空间的一部分.也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区.缓冲区根据其对应的是输入设备还是输出 ...

  6. ES6中Promise对象个人理解

    Promise是ES6原生提供的一个用来传递异步消息的对象.它减少了传统ajax金字塔回调,可以将异步操作以同步操作的流程表达出来使得代码维护和可读性方面好很多. Promise的状态: 既然是用来传 ...

  7. Nio编程模型总结

    终于,这两天的考试熬过去了, 兴致冲冲的来整理笔记来, 这篇博客是我近几天的NIO印象笔记汇总,记录了对Selector及Selector的重要参数的理解,对Channel的理解,常见的Channel ...

  8. 简论数据库乐观悲观锁与并发编程中的CAS

    为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/ShiJiaqi. http://www.cnblogs.com/shijiaqi1066/p/5783205. ...

  9. Java网络编程和NIO详解4:浅析NIO包中的Buffer、Channel 和 Selector

    Java网络编程与NIO详解4:浅析NIO包中的Buffer.Channel 和 Selector 转自https://www.javadoop.com/post/nio-and-aio 本系列文章首 ...

随机推荐

  1. Java多线程(二) —— 深入剖析ThreadLocal

    对Java多线程中的ThreadLocal类还不是很了解,所以在此总结一下. 主要参考了http://www.cnblogs.com/dolphin0520/p/3920407.html 中的文章. ...

  2. 浅谈C++/JAVA/C#运行机制和执行效率

    估计有很多同学都对C++/JAVA/C#这三大热门语言的运行机制和执行效率有或多或少的困惑,自己也有,但是经过前期的学习,了解了三者在这两方面的区别,就废话不说了,进入主题吧.         一.运 ...

  3. 打豪车应用:uber详细攻略(附100元优惠码)

    在嘀嘀打车和快的打车交战热闹的时候,美国的打车应用uber进入中国.与在美国以个人司机注册做 Uber 司机为主的模式不同,Uber 在中国采用与租车公司合作.由租车公司提供车辆和司机的模式,同时中文 ...

  4. 【刷题】BZOJ 3591 最长上升子序列

    Description 给出1~n的一个排列的一个最长上升子序列,求原排列可能的种类数. Input 第一行一个整数n. 第二行一个整数k,表示最长上升子序列的长度. 第三行k个整数,表示这个最长上升 ...

  5. AtCoder Grand Contest 005

    AtCoder Grand Contest 005 A - STring 翻译 给定一个只包含\(ST\)的字符串,如果出现了连续的\(ST\),就把他删去,然后所有位置前移.问最后剩下的串长. 题解 ...

  6. Educational Codeforces Round 48

    题目地址 Edu48 A.Death Note 翻译 你有一个无穷页的本子,每一页可以写\(m\)个名字, 你在第\(i\)天要写\(a_i\)个名字,如果这一页恰好写满了,你就会翻页, 问每天的翻页 ...

  7. Composer 更换为国内镜像源(Packagist 镜像)

    安装lavavel步骤: 安装composer (需要开启php_openssl扩展,否则报错) (https://getcomposer.org/) 到github下载laravel的最新发行版 ( ...

  8. 解决SurfaceView调用setZOrderOnTop(true)遮挡其他控件

    解决SurfaceView调用setZOrderOnTop(true)遮挡其他控件的问题 http://marller.blog.51cto.com/8699646/1762028 FAQ: Surf ...

  9. 2018.9.22 Bubble Cup 11-Finals(Online Mirror,Div.2)

    感受了一下ACM的感觉,然后被神题和神犇们暴踩了 夭寿啦,机房大佬非法组队啊 比赛前i207M插的“怕不是不到九点就要弃疗”的flag成功生效 一开始先扫了一遍题,我一开始以为A题是个扫一遍的题,然后 ...

  10. bzoj 3853 : GCD Array

    搬运题解Claris:1 n d v相当于给$a[x]+=v[\gcd(x,n)=d]$ $\begin{eqnarray*}&&v[\gcd(x,n)=d]\\&=& ...