5.4 Buffer详解
如你所见,在NIO中,数据的读写操作始终是与缓冲区相关联的。Channel将数据读入缓冲区,然后我们又从缓冲区访问数据。写数据时,首先将要发送的数据按顺序填入缓冲区。基本上,缓冲区只是一个列表,它的所有元素都是基本数据类型(通常为字节型)。缓冲区是定长的,它不像一些类那样可以扩展容量(例如,List,StringBuffer等)。注意,ByteBuffer是最常用的缓冲区,因为:1)它提供了读写其他数据类型的方法,2)信道的读写方法只接收ByteBuffer。那么其他类型的信道,如IntBuffer,DoubleBuffer等的优点在哪儿呢?稍安毋躁!答案将在第5.4.6节揭晓。
5.4.1 Buffer索引
缓冲区不仅仅是用来存放一组元素的列表。在读写数据时,它具有内部状态来跟踪缓冲区的当前位置,以及有效可读数据的结束位置等。为了实现这些功能,每个缓冲区维护了指向其元素列表的4个索引,如表5-1所示。(不久我们将看到如何使用缓冲区的各种方法来修改索引值。)
position和limit之间的距离指示了可读取/存入的字节数。Java中提供了两个方便的方法来计算这个距离。
ByteBuffer:剩余字节
当缓冲区至少还有一个元素时,hasRemaining()方法返回true,remaining()方法返回剩余元素的个数。
在这些变量中,以下关系保持不变:
0≤mark≤position≤limit≤capacity
mark变量的值“记录”了一个将来可返回的位置,reset()方法则将position的值还原成上次调用mark()方法后的position值(除非这样做会违背上述的不变关系)。