文档章节

IoBuffer和ByteBuffer

Gaischen
 Gaischen
发布于 2012/10/24 19:30
字数 1044
阅读 10754
收藏 20

最近在做通信和传输的项目,大量的使用NIOMina,虽然之前一直对这部分比较关注,但是还没有好好的总结一下这方面的内容。今天想写点儿NIO里最基本的一个类ByteBuffer。至于Mina中的IoBuffer,我们可以先看Mina API中的描述:

A byte buffer used by MINA applications. This is a replacement for ByteBuffer. Please refer to ByteBuffer documentation for preliminary usage

当然,接下去也有写到:MINA does not use NIO ByteBuffer directly for two reasons,至于这Two Reasons,我们将在后面的比较中展开。

ByteBuffer继承了Buffer,对Buffer的理解可以说是NIO的入门。在Buffer中有4个重要的Attributes

Capacity: the capacity is set when the buffer is created and can never be changed

Limit: the first element of the buffer that should not be read or written

Position: the index of the next element to be read or written

Mark: a remembered position. Calling mark() set mark=position

他们的关系如下:0<=mark<=position<=limit<=capacity。


通俗的讲:

Capacity:开的内存的大小,一旦设定了,就不能更改了。注意,这里指的是原生的NIO

Limit:可以分读写来统计。在写入buffer时,limit表示有多少空间可以写入。在从buffer写出时,limit表示有多少可以写出。

Position:下一个要被读或写的位置。

Mark:标记位,可以记住某个position,方便后续操作。

 

对于ByteBuffer有如下常用的操作:

flip()::读写模式的转换。

rewind() :将 position 重置为 0 ,一般用于重复读。

clear() :清空 buffer ,准备再次被写入 (position 变成 0 , limit 变成 capacity) 。

compact(): 将未读取的数据拷贝到 buffer 的头部位。

mark() 、 reset():mark 可以标记一个位置, reset 可以重置到该位置。

get()getShort()等一系列get操作:获取ByteBuffer中的内容,当然这里get的内容都是从position开始的,所以要时刻注意position。每次get之后position都会改变。Position的变化是根据你get的类型,如果是short,那就是2byte,如果是int,那就是增加4byte,即32

put()putShort()等一系列put操作:向ByteBuffer添加内容,这里put的内容都是从position开始的。每次put之后position都会改变。

当然还有allocatehasRemaining等常用的方法,不过这些用法一般都不会出错,使用起来和4attributes也没有多大相关。特别注意:Buffers are not thread-safe. If you want to access a given buffer concurrently from multiple threads, you will need to do your own synchronization prior to accessing the buffer.至于Buffer或者ByteBuffer有什么用?那太多了,只要涉及到传输、涉及到通信,都可以用到。当然你也可以用它最原始的含义,缓冲。

 

好了NIOByteBuffer告一段落,接下来先说IoBuffer中说不用ByteBufferTwo Reasons

It doesn't provide useful getters and putters such as fill, get/putString, and get/putAsciiInt() enough.

It is difficult to write variable-length data due to its fixed capacity

看好了,对于第一点我想也没什么,增加了更实用的getString。关键是第二点,IoBuffer实现了Auto ExpandAuto Shrink。这就意味了,capacity可以根据传输内容的大小自动变更了。在使用上,我们可以这样写:

IoBuffer buf = IoBuffer.allocate(1024).setAutoExpand(true);
IoBuffer的源码中,大部分都使用了原生的 ByteBuffer来实现,这部分采用 allocator来实现。


/** The allocator used to create new buffers */
private static IoBufferAllocator allocator = new SimpleBufferAllocator();
在SimpleBufferAllocator的其中一段allocate:



public ByteBuffer allocateNioBuffer(int capacity, boolean direct) {
        ByteBuffer nioBuffer;
        if (direct) {
            nioBuffer = ByteBuffer.allocateDirect(capacity);
        } else {
            nioBuffer = ByteBuffer.allocate(capacity);
        }
        return nioBuffer;
    }
至于其他操作,和 ByteBuffer 类似。

贴一段Reilly - Java NIO中的一段代码作为结束,后续更多的Mina相关会根据开发进度给出介绍:



import java.nio.CharBuffer;
 
public class BufferFillDrain {
private static int index = 0;
private static String[] strings = { "A random string value",
"The product of an infinite number of monkeys",
"Hey hey we're the Monkees" };
 
private static boolean fillBuffer(CharBuffer buffer) {
 
if (index >= strings.length) {
return false;
}
String string = strings[index++];
 
for (int i = 0; i < string.length(); i++) {
buffer.put(string.charAt(i));
}
return true;
}
 
private static void drainBuffer(CharBuffer buffer){
while(buffer.hasRemaining()){
System.out.println(buffer.get());
}
System.err.println("");
}
 
public static void main(String[] args) {
CharBuffer buffer=CharBuffer.allocate(100);
while(fillBuffer(buffer)){
buffer.flip();
drainBuffer(buffer);
buffer.clear();
}
 
}
}
因为之前做笔记的时候用的都是英文,所以好多都没有翻译过来,更好的文档是官方的文档,谢谢观赏。


© 著作权归作者所有

Gaischen

Gaischen

粉丝 827
博文 55
码字总数 73789
作品 1
杭州
架构师
私信 提问
加载中

评论(14)

edcSam
edcSam
cool
peterchain
peterchain
不flip,就读会报错。java.nio.BufferUnderflowException
peterchain
peterchain
#此处输入软件名#Eclipse
/**
   * @param args
   */
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    //自动扩展,自动收缩
    IoBuffer in = IoBuffer.allocate(10).setAutoExpand(true).setAutoShrink(true);
    in.putInt(-100) ; //一次性向缓冲写入int类型的,占4个字节
    in.putUnsigned(1); //一次性写入一个字节的无符号整形数值,占一个字节
    in.putUnsignedInt(111); //一次性向缓冲写入无符号的int类型数值,占4个字节
    in.putUnsigned(2); //一次性写入一个字节的无符号整形数值,占一个字节
    System.out.println("position: "+in.position());
    //in.flip();
    System.out.println("position: "+in.position());
    
    System.out.println(in.getInt());
    System.out.println(in.getUnsigned());
    System.out.println(in.getUnsignedInt());
    System.out.println(in.getUnsigned());
    
    System.out.println("position: "+in.position());
  }
peterchain
peterchain
以便读取
peterchain
peterchain
flip是将 position 和 limit置到首位,一边读取。因为往buffer里面放数据的时候,每放一次,position和 limit就会变吧。
zzuqiang
zzuqiang
写的挺不错了!我喜欢0
zzuqiang
zzuqiang
写的挺不错了!我喜欢0
zzuqiang
zzuqiang
写的挺不错了!我喜欢0
y
yuwei
flip的意思我的理解是本次的缓冲要结束了,可以把缓冲中的内容输出了,一般都用在向输出流写之前把调用该方法。
iq527
iq527

引用来自“伊森papa”的评论

还是不太理解flip()的作用,博主本文中提到"flip()::读写模式的转换。"。
但是如果调用两次flip()的话,并不是“转换”的效果,而是position=0,limit=0。

可以仔细的看下flip()的文档描述, 上面已经描述的很清楚了. Flips this buffer. The limit is set to the current position and then the position is set to zero.
连续调用两次flip的话, 一般您是不会这么操作的, 对吧?
Mina源码阅读笔记(二)- IoBuffer的封装

上一篇《整体解读》的延续。。 在阅读IoBuffer源码之前,我们先看Mina对IoBuffer的描述:A byte buffer used by MINA applications. This is a replacement for ByteBuffer. 这是一个对ByteB...

Gaischen
2012/11/20
16.6K
16
mina read方法出现BufferUnderflowException异常的解决办法

现象: 先连续发几十个很小很小的包(<10 byte) 再突然发一个大小64byte的包 这时你会发现mina就会出现以下错误 经过对mina的分析,这是由对包长度不对做成的(即,我们发的包长是大于64byte的...

JavaGG
2009/02/17
76.8K
1
mina read方法出现BufferUnderflowException异常的解决办法

现象: 先连续发几十个很小很小的包(<10 byte) 再突然发一个大小64byte的包 这时你会发现mina就会出现以下错误 java.nio.BufferUnderflowException at java.nio.HeapByteBuffer.get(Unknown...

JavaGG
2010/03/24
1K
0
MINA 3.0.0-M1 版本发布

MINA 2.0 正式版还没发布,3.0 已经在开始了,不知道在搞什么? Bug [DIRMINA-574] - ClassCastException when a message is written on a closed session. [DIRMINA-585] - Visibility iss......

红薯
2009/02/06
4K
1
MiNa 实现多人聊天室程序

开发环境: System:Windows JavaSDK:1.6 IDE:eclipse、MyEclipse 6.6 开发依赖库: Jdk1.4+、mina-core-2.0.4.jar、slf4j-api-1.5.11.jar、slf4j-log4j12-1.5.11.jar Email:hoojo_@126.......

ibm_hoojo
2012/08/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

64.监控平台介绍 安装zabbix 忘记admin密码

19.1 Linux监控平台介绍 19.2 zabbix监控介绍 19.3/19.4/19.6 安装zabbix 19.5 忘记Admin密码如何做 19.1 Linux监控平台介绍: 常见开源监控软件 ~1.cacti、nagios、zabbix、smokeping、ope...

oschina130111
昨天
64
0
当餐饮遇上大数据,嗯真香!

之前去开了一场会,主题是「餐饮领袖新零售峰会」。认真听完了餐饮前辈和新秀们的分享,觉得获益匪浅,把脑子里的核心纪要整理了一下,今天和大家做一个简单的分享,欢迎感兴趣的小伙伴一起交...

数澜科技
昨天
26
0
DNS-over-HTTPS 的下一代是 DNS ON BLOCKCHAIN

本文作者:PETER LAI ,是 Diode 的区块链工程师。在进入软件开发领域之前,他主要是在做工商管理相关工作。Peter Lai 也是一位活跃的开源贡献者。目前,他正在与 Diode 团队一起开发基于区块...

红薯
昨天
44
0
CC攻击带来的危害我们该如何防御?

随着网络的发展带给我们很多的便利,但是同时也带给我们一些网站安全问题,网络攻击就是常见的网站安全问题。其中作为站长最常见的就是CC攻击,CC攻击是网络攻击方式的一种,是一种比较常见的...

云漫网络Ruan
昨天
27
0
实验分析性专业硕士提纲撰写要点

为什么您需要研究论文的提纲? 首先当您进行研究时,您需要聚集许多信息和想法,研究论文提纲可以较好地组织你的想法, 了解您研究资料的流畅度和程度。确保你写作时不会错过任何重要资料以此...

论文辅导员
昨天
44
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部