2.6.2 缓冲区数据结构
在使用内存映射时,我们创建了单一的缓冲区横跨整个文件或我们感兴趣的文件区域。我们还可以使用更多的缓冲区来读写大小适度的信息块。
本节将简要地介绍Buffer对象上的基本操作。缓冲区是由具有相同类型的数值构成的数组,Buffer类是一个抽象类,它有众多的具体子类,包括ByteBuffer、CharBuffer、DoubleBuffer、IntBuffer、LongBuffer和ShortBuffer。
注意:StringBuffer类与这些缓冲区没有关系。
在实践中,最常用的将是ByteBuffer和CharBuffer。如图2-10所示,每个缓冲区都具有:
- 一个容量,它永远不能改变。
- 一个读写位置,下一个值将在此进行读写。
- 一个界限,超过它进行读写是没有意义的。
- 一个可选的标记,用于重复一个读入或写出操作。
这些值满足下面的条件:
0≤标记≤位置≤界限≤容量
使用缓冲区的主要目的是执行“写,然后读入”循环。假设我们有一个缓冲区,在一开始,它的位置为0,界限等于容量。我们不断地调用put将值添加到这个缓冲区中,当我们耗尽所有的数据或者写出的数据量达到容量大小时,就该切换到读入操作了。
这时调用f?lip方法将界限设置到当前位置,并把位置复位到0。现在在remaining方法返回正数时(它返回的值是“界限-位置”),不断地调用get。在我们将缓冲区中所有的值都读入之后,调用clear使缓冲区为下一次写循环做好准备。clear方法将位置复位到0,并将界限复位到容量。
如果你想重读缓冲区,可以使用rewind或mark/reset方法,详细内容请查看API
注释。
要获取缓冲区,可以调用诸如ByteBuffer.allocate或ByteBuffer.wrap这样的静态方法。
然后,可以用来自某个通道的数据填充缓冲区,或者将缓冲区的内容写出通道中。例如:
这是一种非常有用的方法,可以替代随机访问文件。