Mina的IoBuffer类getSlice方法略坑

来源:互联网 发布:移民文案知乎 编辑:程序博客网 时间:2024/06/07 02:29

最近用到Mina框架做底层通讯,发现了IoBuffer.getSlice方法是用有点不同

先看官方文档(http://mina.apache.org/mina-project/xref/)具体页面:http://mina.apache.org/mina-project/xref/org/apache/mina/core/buffer/IoBuffer.html

844     /**845      * Get a new IoBuffer containing a slice of the current buffer846      * 847      * @param index The position in the buffer 848      * @param length The number of bytes to copy849      * @return the new IoBuffer850      */851     public abstract IoBuffer getSlice(int index, int length);852 853     /**854      * Get a new IoBuffer containing a slice of the current buffer855      * 856      * @param length The number of bytes to copy857      * @return the new IoBuffer858      */859     public abstract IoBuffer getSlice(int length);

E文很简单我就不再翻译了,然后我们看测试代码

    public static void main(String[] args){        IoBuffer buff = IoBuffer.allocate(1024).setAutoExpand(true);        buff.put("a".getBytes());        buff.put("b".getBytes());        buff.put("c".getBytes());        buff.put("d".getBytes());        buff.flip();        IoBuffer slice = buff.getSlice(2,1);        System.out.println("after Slice,orginal IoBuffer:"+buff.getHexDump());        System.out.println("after Slice,new IoBuffer====="+slice.getHexDump());    }

运行结果如下:
after Slice,orginal IoBuffer:61 62 63 64
after Slice,new IoBuffer=====63

如图


IoBuffer.getSlice方法是多态的,我先用getSlice(int index, int length)

可以看出getSlice方法后对原IoBuffer是没有影响的,新的IoBuffer是切片的内容


然后我们来看重载的另外个方法getSlice(int length)

    public static void main(String[] args){        IoBuffer buff = IoBuffer.allocate(1024).setAutoExpand(true);        buff.put("a".getBytes());        buff.put("b".getBytes());        buff.put("c".getBytes());        buff.put("d".getBytes());        buff.flip();        IoBuffer slice = buff.getSlice(2);        System.out.println("after Slice,orginal IoBuffer:"+buff.getHexDump());        System.out.println("after Slice,new IoBuffer====="+slice.getHexDump());    }

运行结果如下:

after Slice,orginal IoBuffer:63 64
after Slice,new IoBuffer=====61 62

如图:


这个getSlice后对原IoBuffer有影响了。

新IoBuffer是截取position默认从0开始的2Byte,position的位置同时发生变化。

这重载变化的有点出乎意料了!

getSlice(int length)前最好先mark()下,这样后面如果需要恢复position可以reset()恢复;

getSlice(int begin,int length)随便用,不会有啥不良影响。


=====================================================================================================

追加:

看了这两个方法的实现源码

在类org.apache.mina.core.buffer.AbstractIoBuffer

    /**     * {@inheritDoc}     */    @Override    public final IoBuffer getSlice(int index, int length) {        if (length < 0) {            throw new IllegalArgumentException("length: " + length);        }        int pos = position();        int limit = limit();        if (index > limit) {            throw new IllegalArgumentException("index: " + index);        }        int endIndex = index + length;        if (endIndex > limit) {            throw new IndexOutOfBoundsException("index + length (" + endIndex + ") is greater " + "than limit ("                    + limit + ").");        }        clear();        limit(endIndex);        position(index);        IoBuffer slice = slice();        limit(limit);        position(pos);        return slice;    }    /**     * {@inheritDoc}     */    @Override    public final IoBuffer getSlice(int length) {        if (length < 0) {            throw new IllegalArgumentException("length: " + length);        }        int pos = position();        int limit = limit();        int nextPos = pos + length;        if (limit < nextPos) {            throw new IndexOutOfBoundsException("position + length (" + nextPos + ") is greater " + "than limit ("                    + limit + ").");        }        limit(pos + length);        IoBuffer slice = slice();        position(nextPos);        limit(limit);        return slice;    }

源码中可以看出getSlice(int length)中确实把position的位置调整了,不知道写源码的人出于什么目的,这个方法中已经定义了nextPos=pos+length了,接下来的limit(pos+length)为何不直接使用limit(nextPos),感觉他这里似乎是写晕了。。。。。。

0 0
原创粉丝点击