概念讲解,转自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与C++相比增加和缺少的特性--持续更新

    缺少的特性 java值类型中没有无符号数 java没有运算符重载语法 java中没有struct和union等用户自定义值类型 java中没有虚函数的概念,所有函数默认具有虚函数的特性 java采用单 ...

  2. C#实体对象序列化成Json,并让字段的首字母小写

    引言:最近在工作中遇到与某些API对接的post的数据需要将对象的字段首字母小写.解决办法有两种:第一种:使用对象的字段属性设置JsonProperty来实现(不推荐,因为需要手动的修改每个字段的属性 ...

  3. 用join取代not in

    写了好几个页面,速度都上不去,瓶颈在于SQL查询.太多的表,太多的not in,总是从一大推表和数据中筛选出一点数据.看了很多关于SQL优化的文章,都强烈要求不要太多使用not in查询,最好用表连接 ...

  4. sqlserver创建同义词

    https://blog.csdn.net/anderslu/article/details/53433841?utm_source=itdadao&utm_medium=referral 例 ...

  5. CodeForces - 988C(STL大法好)

    请你找出两个编号不同的数列,并从这两个数列中各恰好删除一个数,使得这两个数列的和相等. 用vector存每一个数 用map标记 即可 #include <bits/stdc++.h> us ...

  6. Machine Learning CodeForces - 940F(带修改的莫队)

    题解原文地址:https://www.cnblogs.com/lujiaju6555/p/8468709.html 给数组a,有两种操作,1 l r查询[l,r]中每个数出现次数的mex,注意是出现次 ...

  7. Leetcode模拟题篇

    43. Multiply Strings 高精度非负整数的乘法. string multiply(string num1, string num2) { '); ; <= i; --i) { ; ...

  8. 【hihocoder编程练习赛9】闰秒

    题目链接 #include<stdio.h> #include<string.h> #include<algorithm> #include<math.h&g ...

  9. 【CF472G】Design Tutorial: Increase the Constraints

    Description 给出两个01序列\(A\)和\(B\) 要求回答\(q\)个询问每次询问\(A\)和\(B\)中两个长度为\(len\)的子串的哈明距离 ​ 哈明距离的值即有多少个位置不相等 ...

  10. Android资源混淆 + 混淆忽略 .so库

    安装包立减1M--微信Android资源混淆打包工具http://mp.weixin.qq.com/s?__biz=MzAwNDY1ODY2OQ==&mid=208135658&idx ...