最近用到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 buffer
846 *
847 * @param index The position in the buffer
848 * @param length The number of bytes to copy
849 * @return the new IoBuffer
850 */
851 public abstract IoBuffer getSlice(int index, int length);
852
853 /**
854 * Get a new IoBuffer containing a slice of the current buffer
855 *
856 * @param length The number of bytes to copy
857 * @return the new IoBuffer
858 */
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),感觉他这里似乎是写晕了。。。。。。