所有的缓冲区都具有四个属性来提供关于其所包含的数据元素的信息。它们是:
容量(Capacity)
缓冲区能够容纳的数据元素的最大数量。这一容量在缓冲区创建时被设定,并且永远不能
被改变。
上界(Limit)
缓冲区的第一个不能被读或写的元素。或者说,缓冲区中现存元素的计数。
位置(Position)
下一个要被读或写的元素的索引。位置会自动由相应的 get( )和 put( )函数更新。
标记(Mark)
一个备忘位置。调用 mark( )来设定 mark = postion。调用 reset( )设定 position =
mark。标记在设定前是未定义的(undefined)。
这四个属性之间总是遵循以下关系:
0 <= mark <= position <= limit <= capacity
?
package java.nio;
public abstract class Buffer {
public final int capacity( )
public final int position( )
public final Buffer position (int newPosition)
public final int limit( )
public final Buffer limit (int newLimit)
public final Buffer mark( )
public final Buffer reset( )
public final Buffer clear( )
public final Buffer flip( )
public final Buffer rewind( )
public final int remaining( )
public final boolean hasRemaining( )
public abstract boolean isReadOnly( );
}
关于这个 API 有一点要注意的是,像 clear()这类函数,您通常应当返回 void,而不
是 Buffer 引用。这些函数将引用返回到它们在(this)上被引用的对象。这是一个允许级
联调用的类设计方法。级联调用允许这种类型的代码:
buffer.mark( );
buffer.position(5);
buffer.reset( );
被简写为:
buffer.mark().position(5).reset( );
?
上界属性指明了缓冲区有效内容的末端。我们需要将上界属性设置为当前位置,然后将位
置重置为 0。我们可以人工用下面的代码实现:
buffer.limit(buffer.position()).position(0);
但这种从填充到释放状态的缓冲区翻转是 API 设计者预先设计好的,他们为我们提供了
一个非常便利的函数:
Buffer.flip();
Flip()函数将一个能够继续添加数据元素的填充状态的缓冲区翻转成一个准备读出元素
的释放状态。
Rewind()函数与 flip()相似,但不影响上界属性。它只是将位置值设回 0。您可以使
用 rewind()后退,重读已经被翻转的缓冲区中的数据。
如果将缓冲区翻转两次会怎样呢?它实际上会大小变为 0。按照图 2.5 的相同步骤对缓冲
区进行操作;把上界设为位置的值,并把位置设为 0。上界和位置都变成 0。尝试对缓冲区上
位置和上界都为 0 的 get()操作会导致 BufferUnderflowException 异常。而 put()则
?
会导致 BufferOverflowException 异常。
布尔函数 hasRemaining()会在释放缓冲区时告诉您是否已经达到缓冲区的上界。以下
是一种将数据元素从缓冲区释放到一个数组的方法(在 2.1.10 小节中,我们将学到进行批量
传输的更高效的方法)。
for (int i = 0; buffer.hasRemaining( ), i++) {
myByteArray [i] = buffer.get( );
}
作为选择,remaining()函数将告知您从当前位置到上界还剩余的元素数目。您也可以
通过下面的循环来释放图 2-5 所示的缓冲区。
int count = buffer.remaining( );
for (int i = 0; i < count, i++) {
myByteArray [i] = buffer.get( );
?
}
一旦缓冲区对象完成填充并释放,它就可以被重新使用了。Clear()函数将缓冲区重置
为空状态。它并不改变缓冲区中的任何数据元素,而是仅仅将上界设为容量的值,并把位置设
?
回 0。这使得缓冲区可以被重新填入。
?
demo:
?
package nio; import java.nio.CharBuffer; public class NIO_1 { 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","Opening act for the Monkees: Jimi Hendrix", "'Scuse me while I kiss this fly","Help Me! Help Me!", }; 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); } public static void main(String[] argv) throws Exception { CharBuffer buffer = CharBuffer.allocate(100); while (fillBuffer(buffer)) { buffer.flip(); drainBuffer(buffer); buffer.clear(); } } }
?