java nio中buffer缓冲区一些方法

本文属于转载,原文地址

http://cheng330301560.iteye.com/blog/1028820


Flip()翻转

我们已经写满了缓冲区,现在我们必须准备将其清空。我们想把这个缓冲区传递给一个通道,以使内容能被全部写出。但如果通道现在在缓冲区上执行get(),那么它将从我们刚刚插入的有用数据之外取出未定义数据。如果我们将位置值重新设为0,通道就会从正确位置开始获取,但是它是怎样知道何时到达我们所插入数据末端的呢?这就是上界属性被引入的目的。上界属性指明了缓冲区有效内容的末端。我们需要将上界属性设置为当前位置,然后将位置重置为0。我们可以人工用下面的代码实现: buffer.limit(buffer.position()).position(0); 但这种从填充到释放状态的缓冲区翻转是API设计者预先设计好的,他们为我们提供了一个非常便利的函数: Buffer.flip(); Flip()函数将一个能够继续添加数据元素的填充状态的缓冲区翻转成一个准备读出元素的释放状态。比如:


我们定义一个容量为10的字节缓冲区,这里它有一个上界limit和当前位置position,limit这时的大小是10,假如我们这时加入3个数字,这时position位置指向4,这时你如果想读数据的话,使用这个方法后,position变为0,而limit变为4

Rewind()

与flip()相似,但不影响上界属性。它只是将位置值设回0。您可以使用rewind()后退,重读已经被翻转的缓冲区中的数据。

hasRemaining()

布尔函数会在释放缓冲区时告诉您是否已经达到缓冲区的上界。以下是一种将数据元素从缓冲区释放到一个数组的方法


for (int i = 0; buffer.hasRemaining( ), i++)

{ myByteArray [i] = buffer.get( ); }

 作为选择,remaining()函数将告知您从当前位置到上界还剩余的元素数目


int count = buffer.remaining( );

for (int i = 0; i < count, i++)

 { myByteArray [i] = buffer.get( ); }


Clear()

Clear()函数将缓冲区重置为空状态。它并不改变缓冲区中的任何数据元素,而是仅仅将上界设为容量的值,并把位置设回0


压缩compact()

有时,您可能只想从缓冲区中释放一部分数据,而不是全部,然后重新填充。为了实现这一点,未读的数据元素需要下移以使第一个元素索引为0。尽管重复这样做会效率低下,但这有时非常必要,而API对此为您提供了一个compact()函数。这一缓冲区工具在复制数据时要比您使用get()和put()函数高效得多.还要注意的是,位置已经被设为被复制的数据元素的数目。也就是说,缓冲区现在被定位在缓冲区中最后一个“存活”元素后插入数据的位置。最后,上界属性被设置为容量的值,因此缓冲区可以被再次填满。调用compact()的作用是丢弃已经释放的数据,保留未释放的数据,并使缓冲区对重新填充容量准备就绪.如果您想在压缩后释放数据,缓冲区会像之前所讨论的那样需要被翻转.

mark()
缓冲区的标记在 mark( )函数被调用之前是未定义的,调用时标记被设为当前位置的值。reset( )函数将位置设为当前的标记值。如果标记值未定义,调用 reset( )将导致 InvalidMarkException 异常。一些缓冲区函数会抛弃已经设定的标记(rewind( ),clear( ),以及 flip( )总是抛弃标记)。如果新设定的值比当前的标记小,调用limit( )或 position( )带有索引参数的版本会抛弃标记。


equals()
如果每个缓冲区中剩余的内容相同,那么 equals( )函数将返回 true,否则返回 false。
两个缓冲区被认为相等的充要条件是:
      两个对象类型相同。包含不同数据类型的 buffer 永远不会相等,而且 buffer绝不会等于非 buffer 对象。
      两个对象都剩余同样数量的元素。Buffer 的容量不需要相同,而且缓冲区中剩余数据的索引也不必相同。但每个缓冲区中剩余元素的数目(从位置到上界)必须相同。
      在每个缓冲区中应被 Get()函数返回的剩余数据元素序列必须一致。

compareTo( )
比较是针对每个缓冲区内剩余数据进行的,与它们在 equals( )中的方式相同,直到不相等的元素被发现或者到达缓冲区的上界。如果一个缓冲区在不相等元素发现前已经被耗尽,较短的缓冲区被认为是小于较长的缓冲区。


字节顺序order()
public abstract class CharBuffer extends Buffer implements Comparable, CharSequence
{
       // This is a partial API listing
       public final ByteOrder order( )
}
这个函数从 ByteOrder 返回两个常量之一。对于除了 ByteOrder 之外的其他缓冲区类,字节顺序是一个只读属性,并且可能根据缓冲区的建立方式而采用不同的值。除了ByteBuffer , 其 他 通 过 分 配 或 包 装 一 个 数 组 所 创 建 的 缓 冲 区 将 从 order() 返 回 与ByteOrder.nativeOrder()相同的数值。这使因为包含在缓冲区中的元素在 JVM 中将会被作为基本数据直接存取。
ByteBuffer 类有所不同:默认字节顺序总是 ByteBuffer.BIG_ENDIAN,无论系统的固有字节顺序是什么。Java 的默认字节顺序是大端字节顺序,这允许类文件等以及串行化的对象可以在任何 JVM 中工作。如果固有硬件字节顺序是小端,这会有性能隐患。在使用固有硬件字节顺序时,将 ByteBuffer 的内容当作其他数据类型存取(很快就会讨论到)很可能高效得多。

很可能您会对为什么 ByteBuffer 类需要一个字节顺序设定这一问题感到困惑。字节就是字节,对吗?当然,但是如您不久将在 2.4.4 节所看到的那样,ByteBuffer 对象像其他基本数据类型一样,具有大量便利的函数用于获取和存放缓冲区内容。这些函数对字节进行编码或解码的方式取决于 ByteBuffer 当前字节顺序的设定。

ByteBuffer 的 字 符 顺 序 设 定 可 以 随 时 通 过 调 用 以 ByteOrder.BIG_ENDIAN 或ByteOrder.LITTL_ENDIAN 为参数的 order()函数来改变。

如果一个缓冲区被创建为一个 ByteBuffer 对象的视图(参见 2.4.3 节),那么order()返回的数值就是视图被创建时其创建源头的 ByteBuffer 的字节顺序设定。视图的字节顺序设定在创建后不能被改变,而且如果原始的字节缓冲区的字节顺序在之后被改变,它也不会受到影响。。






你可能感兴趣的:(nio)