我们准备好了Buffer,现在我们要将它交由Channel处理。现在假设我们填满了一个Buffer,emmmm,然后把它传给Channel对象,Channel对象对buffer调用get方法,然后position自加,会怎么样?IndexOutOfBoundsException被抛出了!
那怎么办?为了让Channel能够处理对象,我们需要把postion重设为你希望它开始处理的位置,顺便再设置limite为现在存储的位置,假设我们需要Channel从头开始处理对象,那么就应该做如下的处理:
buffer.limit(buffer.position()).position(0);
//上面的调用,等同于如下的方法
buffer.flip();
然后概念图就会变成下面这样:
JAVA NIO BUFFER(一)中提到的rewind()方法,只把position设置为0,并不影响limit的位置。
进行完这个操作之后,你就可以试着读取里面的数据
//利用hasRemaining()方法判断Buffer中是否还有数据
for(int i=0;buffer.hasRemaining();i++) {
myByteArray[I]=buffer.get();
}
//上面的方法未必高效,循环体中每次循环都要进行一次判断
//你可以使用remaining()方法,返回剩余的数目
int count = buffer.remaining();
for(int i=0;buffer.count;i++) {
myByteArray[I]=buffer.get();
}
//如果你对Buffer有着惊人的控制,那么不进行数据检查将会是最快的
一旦Buffer使用完毕,它就可以进行复用,clear()方法把一个Buffer重置到一个空的状态。它不更改任何数据,把limit设置为capacity,并把position设置为0.至于里面是不是还有数据?这不重要,Buffer仅仅通过position来判断数据的“死活”为什么一定要将数据置空,这些操作难道不需要时间吗?下面的例子使用到了一些buffer的基本操作:
public class BufferFillDrain {
//原代码作者 Ron Hitchens (ron@ronsoft.com)
private static int index = 0;
private static String[] strings = {
"Hello, this is ZhangJian",
"He likes Eminem",
"Put the dick in the dust",
"And? Fuck the world?",
"Lyrics are great",
"But what I like more",
"is the spirit"
};
public static void main(String[] args) throws Exception {
CharBuffer buffer = CharBuffer.allocate(100);
while( fillBuffer(buffer)) {
buffer.flip();
drainBuffer(buffer);
buffer.clear();
}
}
private static void drainBuffer (CharBuffer buffer) {
while (buffer.hasRemaining()) {
System.out.print(buffer.get());
}
System.out.println("");
}
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;
}
}