2.6.2 缓冲区数据结构

在使用内存映射时,我们创建了单一的缓冲区横跨整个文件或我们感兴趣的文件区域。我们还可以使用更多的缓冲区来读写大小适度的信息块。

本节将简要地介绍Buffer对象上的基本操作。缓冲区是由具有相同类型的数值构成的数组,Buffer类是一个抽象类,它有众多的具体子类,包括ByteBuffer、CharBuffer、DoubleBuffer、IntBuffer、LongBuffer和ShortBuffer。

注意:StringBuffer类与这些缓冲区没有关系。

在实践中,最常用的将是ByteBuffer和CharBuffer。如图2-10所示,每个缓冲区都具有:

·一个容量,它永远不能改变。

·一个读写位置,下一个值将在此进行读写。

·一个界限,超过它进行读写是没有意义的。

·一个可选的标记,用于重复一个读入或写出操作。

图2-10 一个缓冲区

这些值满足下面的条件:

0≤标记≤位置≤界限≤容量

使用缓冲区的主要目的是执行“写,然后读入”循环。假设我们有一个缓冲区,在一开始,它的位置为0,界限等于容量。我们不断地调用put将值添加到这个缓冲区中,当我们耗尽所有的数据或者写出的数据量达到容量大小时,就该切换到读入操作了。

这时调用flip方法将界限设置到当前位置,并把位置复位到0。现在在remaining方法返回正数时(它返回的值是“界限-位置”),不断地调用get。在我们将缓冲区中所有的值都读入之后,调用clear使缓冲区为下一次写循环做好准备。clear方法将位置复位到0,并将界限复位到容量。

如果你想重读缓冲区,可以使用rewind或mark/reset方法,详细内容请查看API注释。

要获取缓冲区,可以调用诸如ByteBuffer.allocate或ByteBuffer.wrap这样的静态方法。

然后,可以用来自某个通道的数据填充缓冲区,或者将缓冲区的内容写出通道中。例如:

这是一种非常有用的方法,可以替代随机访问文件。

java.nio.Buffer 1.4

·Buffer clear()

通过将位置复位到0,并将界限设置到容量,使这个缓冲区为写出做好准备。返回this。

·Buffer flip()

通过将界限设置到位置,并将位置复位到0,使这个缓冲区为读入做好准备。返回this。

·Buffer rewind()

通过将读写位置复位到0,并保持界限不变,使这个缓冲区为重新读入相同的值做好准备。返回this。

·Buffer mark()

将这个缓冲区的标记设置到读写位置,返回this。

·Buffer reset()

将这个缓冲区的位置设置到标记,从而允许被标记的部分可以再次被读入或写出,返回this。

·int remaining()

返回剩余可读入或可写出的值的数量,即界限与位置之间的差异。

·int position()

·void position(int newValue)

返回这个缓冲区的位置。

·int capacity()

返回这个缓冲区的容量。