mina中IOBuffer是Nio中ByteBuffer的衍生类,主要是解决Bytebuffer的两个不足

1、没有提供足够灵活的get/putXXX方法

2、它容量固定,难以写入可变长度的数据

特点:

1、通过allocate分配空间,

2、包装现有的NIOBu和array,

3、自拓展,

4自压缩,

5、衍生缓冲区,

6、可改变缓冲区的分配策略

1.先来学习下ByteBuffer你要了解的东西
摘自 http://blackbeans.iteye.com/blog/836103
这是一篇好文章,对ByteBuff讲的很清楚

查看ByteBuffer的API,看的我是一头雾水,搞不清什么mark、position、limit、flip、reset几个的用法,先看下面的例子:
Java代码 收藏代码

String str = "helloWorld";
ByteBuffer buff = ByteBuffer.wrap(str.getBytes());
System.out.println("position:"+buff.position()+"\t limit:"+buff.limit());
//读取两个字节
buff.get();
buff.get();
System.out.println("position:"+ buff.get(buff.position())+"\t limit:"+buff.limit());
buff.mark();
System.out.println("position:"+buff.position()+"\t limit:"+buff.limit());
buff.flip();
System.out.println("position:"+buff.position()+"\t limit:"+buff.limit());<span style="white-space: pre;"> </span>

Java代码 收藏代码

<pre name="code" class="java">输出结果:
position:0 limit:10
position:2 limit:10
position:2 limit:10
position:0 limit:2
</pre>

我们以每位开发人员熟悉的”helloworld“,用ByteBuffer将字符串包装,由于ByteBuffer是一个抽象类,通过wrap包装的对象将实际返回的是一个HeapByteBuffer对象。由此可知HeapByteBuffer是ByteBuffer的子类,同样的ByteBuffer又是Buffer抽象类的子类。以上提到的mark、position、limit、flip、reset都是出自于Buffer这个抽象类。
下面我们来解析几个方法的,当我们调用了wrap方法后Buffer中初始化的结构是:
注释:
m:mark;
p:position;
L:limit;

初始情况下mark是指向第一个元素之前的的即-1,postion为指向第一个元素为0.而Limit是被赋值为byte[]的长度。
因此这就是打印结果的第一行。
m p L
-1 0 1 2 3 4 5 6 7 8 9
H E L L O W O R L D
当我们连续调用两次get()方法获得两个个字节,每次调用都会触发position++操作,那么此时position就会移动到index = 2的的地方,而这个时候Limit和mark是不会发生变化的。如果将读取的两个字节打印会是H和E,因此执行结果第二行会有position:2 limit:10结果.
m、p L
-1 0 1 2 3 4 5 6 7 8 9
H E L L O W O R L D
读取完毕后我们使用mark,这个时候mark会从-1移动到2和position指向同一个元素,可以看见Limit是不会发生改变的。
m p L
-1 0 1 2 3 4 5 6 7 8 9
H E L L O W O R L D
使用了mark标记的当前的position后,如果们调用flip,这个时候Limit就会指向position的位置,并将mark和position还原为初始值。这样就知道了limit当前的就为2,什么意思呢?就是说当前可以读的字节数是2。
我们可以尝试一下如下代码:

Java代码 收藏代码

System.out.println((char)buff.get()+""+(char)buff.get());

输出结果:he
貌似这也没什么稀奇的,如果你在代码换成

Java代码 收藏代码

// System.out.println((char)buff.get()+""+(char)buff.get()
System.out.println((char)buff.get()+""+(char)buff.get()+""+(char)buff.get());

Java代码 收藏代码

输出结果:<pre name="code" class="java">position:0 limit:10
Exception in thread "main" java.nio.BufferUnderflowException
at java.nio.Buffer.nextGetIndex(Buffer.java:474)
at java.nio.HeapByteBuffer.get(HeapByteBuffer.java:117)
at com.taobao.moxing.notify.Main.main(Main.java:33)position:2 limit:10
position:2 limit:10
position:0 limit:2
</pre>

为什么会抛异常呢?原因是limit的含义就想一个窗口,你当前能读到的数据就是当前窗口限制的(本例中即为2),如果这个窗口之外的所有元素都是不可读的。至此我想你和我就应该明白这几个参数的含义了吧。
而至于reset方法,它是将当前的position设置为0,
rewind是将mark重置为-1,position重置为0;
clear方法是真正的重置,将mark=-1,position=0,limit=capacity(即当前buffer的容量)

2.看看IOBuffer我们需要了解的东西,摘自http://www.360doc.com/content/12/0410/15/9184201_202487090.shtml Apache Mina Server 2.0 中文参考手册

(7.)IoBuffer:

这个接口是对JAVA NIO 的ByteBuffer 的封装,这主要是因为ByteBuffer 只提供了对基本

数据类型的读写操作,没有提供对字符串等对象类型的读写方法,使用起来更为方便,另外,

ByteBuffer 是定长的,如果想要可变,将很麻烦。IoBuffer 的可变长度的实现类似于

StringBuffer。IoBuffer 与ByteBuffer 一样,都是非线程安全的。本节的一些内容如果不

清楚,可以参考java.nio.ByteBuffer 接口。

这个接口有如下常用的方法:

A. static IoBuffer allocate(int capacity,boolean useDirectBuffer):

这个方法内部通过SimpleBufferAllocator 创建一个实例,第一个参数指定初始化容量,第

二个参数指定使用直接缓冲区还是JAVA 内存堆的缓存区,默认为false。

B. void free():

释放缓冲区,以便被一些IoBufferAllocator 的实现重用,一般没有必要调用这个方法,除

非你想提升性能(但可能未必效果明显)。

C. IoBuffer setAutoExpand(boolean autoExpand):

这个方法设置IoBuffer 为自动扩展容量,也就是前面所说的长度可变,那么可以看出长度

可变这个特性默认是不开启的。

D. IoBuffer setAutoShrink(boolean autoShrink):

这个方法设置IoBuffer 为自动收缩,这样在compact()方法调用之后,可以裁减掉一些没

有使用的空间。如果这个方法没有被调用或者设置为false,你也可以通过调用shrink()

方法手动收缩空间。

E. IoBuffer order(ByteOrder bo):

这个方法设置是Big Endian 还是Little Endian,JAVA 中默认是Big Endian,C++和其他

语言一般是Little Endian。

F. IoBuffer asReadOnlyBuffer():

这个方法设置IoBuffer 为只读的。

G. Boolean prefixedDataAvailable(int prefixLength,int maxDataLength):

这个方法用于数据的最开始的1、2、4 个字节表示的是数据的长度的情况,prefixLentgh

表示这段数据的前几个字节(只能是1、2、4 的其中一个)的代表的是这段数据的长度,

maxDataLength 表示最多要读取的字节数。返回结果依赖于等式

remaining()-prefixLength>=maxDataLength,也就是总的数据-表示长度的字节,剩下的字

节数要比打算读取的字节数大或者相等。

H. String getPrefixedString(int prefixLength,CharsetDecoder decoder):

如果上面的方法返回true,那么这个方法将开始读取表示长度的字节之后的数据,注意要

保持这两个方法的prefixLength 的值是一样的。

G、H 两个方法在后面讲到的PrefixedStringDecoder 中的内部实现使用。

IoBuffer 剩余的方法与ByteBuffer 都是差不多的,额外增加了一些便利的操作方法,例如:

IoBuffer putString(String value,CharsetEncoder encoder)可以方便的以指定的编码方

式存储字符串、InputStream asInputStream()方法从IoBuffer 剩余的未读的数据中转为

输入流等。

【MINA】缓存区ByteBuffer和IOBuffer你要了解的常用知识的更多相关文章

  1. Java: 扩大字节缓存区的大小,提升AIO的处理性能(并发性能)

    前些日了,对AIO与NIO的并发性能进行了比较,在低并发的情况下,NIO性能表现比AIO好一些,主要原因是,NIO中可以使用FileChannel.transferTo(long position,  ...

  2. node(Buffer缓存区)

    // 创建buffer类 var buf=new buffer(10); var buf=new buffer([10,20,30,40]); var buf=new buffer("www ...

  3. ACM/ICPC 之 优先级队列+设置IO缓存区(TSH OJ-Schedule(任务调度))

    一个裸的优先级队列(最大堆)题,但也有其他普通队列的做法.这道题我做了两天,结果发现是输入输出太过频繁,一直只能A掉55%的数据,其他都是TLE,如果将输入输出的数据放入缓存区,然后满区输出,可以将I ...

  4. git --如何撤销已放入缓存区(Index区)的修改

    修改或新增的文件通过 git add --all 命令全部加入缓存区(index区)之后,使用 git status 查看状态(git status -s 简单模式查看状态,第一列本地库和缓存区的差异 ...

  5. IntelliJ IDEA修改Output输出缓存区大小【应对:too much output to process】

    IntelliJ IDEA默认的Output输出缓存区大小只有1024KB,超过大小限制的就会被清除,而且还会显示[too much output to process],可通过如下配置界面进行修改O ...

  6. csapp lab3 bufbomb 缓存区溢出攻击 《深入理解计算机系统》

    这个实验主要是熟悉栈,和了解数据缓存区溢出的问题. 数据缓存区溢出:程序每次调用函数时,会把当前的eip指针保存在栈里面,作为被调用函数返回时的程序指针.在被调用程序里面,栈是向下增长的.所有局部变量 ...

  7. Java NIO------基础理论之缓存区

    1.概述:NIO我的理解就是 New IO,是API1.4里提供的新的API,为所有的原始类型做缓存支持. NIO主要的核心组成部分: Buffer(缓存) Channels(通道) Selector ...

  8. 使用pg_buffercache查看缓存区缓存

    PG提供了一个扩展pg_buffercache来查看缓存区的内容. create database test; CREATE DATABASE create extension pg_bufferca ...

  9. JAVA之旅(十七)——StringBuffer的概述,存储,删除,获取,修改,反转,将缓存区的数据存储到数组中,StringBuilder

    JAVA之旅(十七)--StringBuffer的概述,存储,删除,获取,修改,反转,将缓存区的数据存储到数组中,StringBuilder 讲完String,我们来聊聊他的小兄弟 一.StringB ...

随机推荐

  1. HDU 5521 Meeting (最短路,dijstra)

    题意:有N个点,两个人,其中一个人住在点1,另一个人住在点n,有M个点集,集合内的数表示任意两点的距离为dis ,现在问,如果两个人要见面, 需要最短距离是多少,有哪几个点能被当成见面点. 析:分别对 ...

  2. UVALIVE 4970 最小权匹配

    首先贴一下这道题的BNU地址,UVA地址自己找吧. http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=11852 题意:这道题的意思就是,给你N个棋子的 ...

  3. Codeforces Round #219 (Div. 1)(完全)

    戳我看题目 A:给你n个数,要求尽可能多的找出匹配,如果两个数匹配,则ai*2 <= aj 排序,从中间切断,分成相等的两半后,对于较大的那一半,从大到小遍历,对于每个数在左边那组找到最大的满足 ...

  4. 微软IIS服务器的最佳优化工具- IIS Tuner

      dudu的 <让Windows Server 2008 + IIS 7+ ASP.NET 支持10万个同时请求>,里面涉及到需要手工调整参数的地方.在这篇文章中,我们给你介绍一个IIS ...

  5. python视频教程大全

    python3英文视频教程(全87集) http://pan.baidu.com/s/1dDnGBvV python从入门到精通视频(全60集)链接:http://pan.baidu.com/s/1e ...

  6. oracle安装界面中文乱码解决

    在安装oracle时如果我们用的是英文安装没有任何问题,但是我要安装中文的,结果中文界面就出现了乱码了,后来网上找了原因是要安装中文包才可以,下面我来介绍一下. 在Linux的X window里安装o ...

  7. 我所理解的设计模式(C++实现)——备忘录模式(Memento Pattern)

    概述: 我们玩单机游戏的时候总会遇到老婆大人的各位事情,一会去买瓶醋了,一会去打个酱油了,会耽误我们玩游戏的进程,但是此时我们能有“保存游戏”这个宝贝,我们的主基地不会在我们打酱油的时候被对手拆掉. ...

  8. php 算法之切割数组,不用array_chunk(),算法之二,取数组的差值,不用array_diff()

    用php写算法切割数组,不用array_chunk();算法例如以下所看到的. <?php //$array 数组 //$size 每一个数组的个数 //每一个数组元素是否默认键值 functi ...

  9. Android Developers:在命令行构建和运行

    使用Ant构建脚本构建你的应用程序有两种方式:一种用于测试/调试你的引用程序—debug模式—另一种用于构建你最终发布的包-release模式.无论你使用哪种方式构建你的应用程序,它必须在安装在模拟器 ...

  10. online ddl 使用、测试及关键函数栈

    [MySQL 5.6] MySQL 5.6 online ddl 使用.测试及关键函数栈  http://mysqllover.com/?p=547 本文主要分为三个部分,第一部分是看文档时的笔记:第 ...