java nio 缓冲区读写数据(图形详解)
Position
您可以回想一下,缓冲区实际上就是美化了的数组。在从通道读取时,您将所读取的数据放到底层的数组中。 position
变量跟踪已经写了多少数据。更准确地说,它指定了下一个字节将放到数组的哪一个元素中。因此,如果您从通道中读三个字节到缓冲区中,那么缓冲区的 position
将会设置为3,指向数组中第四个元素。
同样,在写入通道时,您是从缓冲区中获取数据。 position
值跟踪从缓冲区中获取了多少数据。更准确地说,它指定下一个字节来自数组的哪一个元素。因此如果从缓冲区写了5个字节到通道中,那么缓冲区的 position
将被设置为5,指向数组的第六个元素。
Limit
limit
变量表明还有多少数据需要取出(在从缓冲区写入通道时),或者还有多少空间可以放入数据(在从通道读入缓冲区时)。
position
总是小于或者等于 limit
。
Capacity
缓冲区的 capacity
表明可以储存在缓冲区中的最大数据容量。实际上,它指定了底层数组的大小 ― 或者至少是指定了准许我们使用的底层数组的容量。
limit
决不能大于 capacity
。
观察变量
我们首先观察一个新创建的缓冲区。出于本例子的需要,我们假设这个缓冲区的 总容量
为8个字节。 Buffer
的状态如下所示:
回想一下 ,limit
决不能大于 capacity
,此例中这两个值都被设置为 8。我们通过将它们指向数组的尾部之后(如果有第8个槽,则是第8个槽所在的位置)来说明这点。
position
设置为0。如果我们读一些数据到缓冲区中,那么下一个读取的数据就进入 slot 0 。如果我们从缓冲区写一些数据,从缓冲区读取的下一个字节就来自 slot 0 。 position
设置如下所示:
由于 capacity
不会改变,所以我们在下面的讨论中可以忽略它。
第一次读取
现在我们可以开始在新创建的缓冲区上进行读/写操作。首先从输入通道中读一些数据到缓冲区中。第一次读取得到三个字节。它们被放到数组中从 position
开始的位置,这时 position 被设置为 0。读完之后,position 就增加到 3,如下所示:
limit
没有改变。
第二次读取
在第二次读取时,我们从输入通道读取另外两个字节到缓冲区中。这两个字节储存在由 position
所指定的位置上, position
因而增加 2:
limit
没有改变。
flip
现在我们要将数据写到输出通道中。在这之前,我们必须调用 flip()
方法。这个方法做两件非常重要的事:
- 它将
limit
设置为当前position
。 - 它将
position
设置为 0。
前一小节中的图显示了在 flip 之前缓冲区的情况。下面是在 flip 之后的缓冲区:
我们现在可以将数据从缓冲区写入通道了。 position
被设置为 0,这意味着我们得到的下一个字节是第一个字节。 limit
已被设置为原来的 position
,这意味着它包括以前读到的所有字节,并且一个字节也不多。
第一次写入
在第一次写入时,我们从缓冲区中取四个字节并将它们写入输出通道。这使得 position
增加到 4,而 limit
不变,如下所示:
第二次写入
我们只剩下一个字节可写了。 limit
在我们调用 flip()
时被设置为 5,并且 position
不能超过 limit
。所以最后一次写入操作从缓冲区取出一个字节并将它写入输出通道。这使得 position
增加到 5,并保持 limit
不变,如下所示:
clear
最后一步是调用缓冲区的 clear()
方法。这个方法重设缓冲区以便接收更多的字节。 Clear
做两种非常重要的事情:
- 它将
limit
设置为与capacity
相同。 - 它设置
position
为 0。
下图显示了在调用 clear()
后缓冲区的状态:
缓冲区现在可以接收新的数据了。
原文:https://www.ibm.com/developerworks/cn/education/java/j-nio/j-nio.html#