java.nio

异常
java.lang.Object
  继承者 java.nio.Buffer
直接已知子类:
ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer

public abstract class Buffer
     
extends Object

一个用于特定基本类型数据的容器。

缓冲区是特定基本类型元素的线性有限序列。除内容外,缓冲区的基本属性还包括容量、限制和位置:

缓冲区的容量 是它所包含的元素的数量。缓冲区的容量不能为负并且不能更改。

缓冲区的限制 是第一个不应该读取或写入的元素的索引。缓冲区的限制不能为负,并且不能大于其容量。

缓冲区的位置 是下一个要读取或写入的元素的索引。缓冲区的位置不能为负,并且不能大于其限制。

对于每个非 boolean 基本类型,此类都有一个子类与之对应。

传输数据

此类的每个子类都定义了两种获取放置 操作:

相对 操作读取或写入一个或多个元素,它从当前位置开始,然后将位置增加所传输的元素数。如果请求的传输超出限制,则相对获取 操作将抛出 BufferUnderflowException,相对放置 操作将抛出 BufferOverflowException;这两种情况下,都没有数据被传输。

绝对 操作采用显式元素索引,该操作不影响位置。如果索引参数超出限制,绝对获取 操作和放置 操作将抛出 IndexOutOfBoundsException

当然,通过适当通道的 I/O 操作(通常与当前位置有关)也可以将数据传输到缓冲区或从缓冲区传出数据。

做标记和重置

缓冲区的标记 是一个索引,在调用 reset 方法时会将缓冲区的位置重置为该索引。并非总是需要定义标记,但在定义标记时,不能将其定义为负数,并且不能让它大于位置。如果定义了标记,则在将位置或限制调整为小于该标记的值时,该标记将被丢弃。如果未定义标记,那么调用 reset 方法将导致抛出 InvalidMarkException

不变式

标记、位置、限制和容量值遵守以下不变式:

0 <= 标记 <= 位置 <= 限制 <= 容量

新创建的缓冲区总有一个 0 位置和一个未定义的标记。初始限制可以为 0,也可以为其他值,这取决于缓冲区类型及其构建方式。一般情况下,缓冲区的初始内容是未定义的。

清除、反转和重绕

除了访问位置、限制、容量值的方法以及做标记和重置的方法外,此类还定义了以下可对缓冲区进行的操作:

  • clear() 使缓冲区为一系列新的通道读取或相对放置 操作做好准备:它将限制设置为容量大小,将位置设置为 0。

  • flip() 使缓冲区为一系列新的通道写入或相对获取 操作做好准备:它将限制设置为当前位置,然后将位置设置为 0。

  • rewind() 使缓冲区为重新读取已包含的数据做好准备:它使限制保持不变,将位置设置为 0。

只读缓冲区

每个缓冲区都是可读取的,但并非每个缓冲区都是可写入的。每个缓冲区类的转变方法都被指定为可选操作,当对只读缓冲区调用时,将抛出 ReadOnlyBufferException。只读缓冲区不允许更改其内容,但其标记、位置和限制值是可变的。可以调用其 isReadOnly 方法确定缓冲区是否为只读。

线程安全

多个当前线程使用缓冲区是不安全的。如果一个缓冲区由不止一个线程使用,则应该通过适当的同步来控制对该缓冲区的访问。

调用链

指定此类中的方法返回调用它们的缓冲区(否则它们不会返回任何值)。此操作允许将方法调用组成一个链;例如,语句序列

 b.flip();
 b.position(23);
 b.limit(42);
可以由以下更紧凑的一个语句代替
 b.flip().position(23).limit(42);

从以下版本开始:
1.4

方法摘要
abstract  Object array()
          返回此缓冲区的底层实现数组(可选操作)
abstract  int arrayOffset()
          返回此缓冲区的底层实现数组中第一个缓冲区元素的偏移量(可选操作)
 int capacity()
          返回此缓冲区的容量。
 Buffer clear()
          清除此缓冲区。
 Buffer flip()
          反转此缓冲区。
abstract  boolean hasArray()
          告知此缓冲区是否具有可访问的底层实现数组。
 boolean hasRemaining()
          告知在当前位置和限制之间是否有元素。
abstract  boolean isDirect()
          告知此缓冲区是否为直接缓冲区
abstract  boolean isReadOnly()
          告知此缓冲区是否为只读缓冲区。
 int limit()
          返回此缓冲区的限制。
 Buffer limit(int newLimit)
          设置此缓冲区的限制。
 Buffer mark()
          在此缓冲区的位置设置标记。
 int position()
          返回此缓冲区的位置。
 Buffer position(int newPosition)
          设置此缓冲区的位置。
 int remaining()
          返回当前位置与限制之间的元素数。
 Buffer reset()
          将此缓冲区的位置重置为以前标记的位置。
 Buffer rewind()
          重绕此缓冲区。
 
从类 java.lang.Object 继承的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

方法详细信息

capacity

public final int capacity()
返回此缓冲区的容量。

返回:
此缓冲区的容量

position

public final int position()
返回此缓冲区的位置。

返回:
此缓冲区的位置

position

public final Buffer position(int newPosition)
设置此缓冲区的位置。如果标记已定义且大于新的位置,则丢弃该标记。

参数:
newPosition - 新位置值;必须为非负且不大于当前限制
返回:
此缓冲区
抛出:
IllegalArgumentException - 如果 newPosition 不满足先决条件

limit

public final int limit()
返回此缓冲区的限制。

返回:
此缓冲区的限制

limit

public final Buffer limit(int newLimit)
设置此缓冲区的限制。如果位置大于新的限制,则将它设置为新限制。如果标记已定义且大于新限制,则丢弃该标记。

参数:
newLimit - 新限制值;必须为非负且不大于此缓冲区的容量
返回:
此缓冲区
抛出:
IllegalArgumentException - 如果 newLimit 不满足先决条件

mark

public final Buffer mark()
在此缓冲区的位置设置标记。

返回:
此缓冲区

reset

public final Buffer reset()
将此缓冲区的位置重置为以前标记的位置。

调用此方法不更改也不丢弃标记的值。

返回:
此缓冲区
抛出:
InvalidMarkException - 如果尚未设置标记

clear

public final Buffer clear()
清除此缓冲区。将位置设置为 0,将限制设置为容量,并丢弃标记。

在使用一系列通道读取或放置 操作填充此缓冲区之前调用此方法。例如:

 buf.clear();     // Prepare buffer for reading
 in.read(buf);    // Read data

此方法不能实际清除缓冲区中的数据,但从名称来看它似乎能够这样做,这样命名是因为它多数情况下确实是在清除数据时使用。

返回:
此缓冲区

flip

public final Buffer flip()
反转此缓冲区。首先将限制设置为当前位置,然后将位置设置为 0。如果已定义了标记,则丢弃该标记。

在一系列通道读取或放置 操作之后,调用此方法为一系列通道写入或相对获取 操作做好准备。例如:

 buf.put(magic);    // Prepend header
 in.read(buf);      // Read data into rest of buffer
 buf.flip();        // Flip buffer
 out.write(buf);    // Write header + data to channel

当将数据从一个地方传输到另一个地方时,经常将此方法与 compact 方法一起使用。

返回:
此缓冲区

rewind

public final Buffer rewind()
重绕此缓冲区。将位置设置为 0 并丢弃标记。

在一系列通道写入或获取 操作之前调用此方法(假定已经适当设置了限制)。例如:

 out.write(buf);    // Write remaining data
 buf.rewind();      // Rewind buffer
 buf.get(array);    // Copy data into array

返回:
此缓冲区

remaining

public final int remaining()
返回当前位置与限制之间的元素数。

返回:
此缓冲区中的剩余元素数

hasRemaining

public final boolean hasRemaining()
告知在当前位置和限制之间是否有元素。

返回:
当且仅当此缓冲区中至少还有一个元素时返回 true

isReadOnly

public abstract boolean isReadOnly()
告知此缓冲区是否为只读缓冲区。

返回:
当且仅当此缓冲区为只读缓冲区时返回 true

hasArray

public abstract boolean hasArray()
告知此缓冲区是否具有可访问的底层实现数组。

如果此方法返回 true,则可以安全地调用 arrayarrayOffset 方法。

返回:
当且仅当此缓冲区有非只读的底层实现数组时返回 true
从以下版本开始:
1.6

array

public abstract Object array()
返回此缓冲区的底层实现数组 (可选操作)

此方法旨在使具有底层实现数组的缓冲区能更有效地传递给本机代码。具体子类为此方法提供更强类型的返回值。

对此缓冲区内容进行修改将导致返回数组的内容被修改,反之亦然。

调用此方法前应调用 hasArray 方法,以确保此缓冲区存在可访问的底层实现数组。

返回:
此缓冲区的底层实现数组
抛出:
ReadOnlyBufferException - 如果此缓冲区存在底层实现数组,但它是只读的
UnsupportedOperationException - 如果此缓冲区不存在可访问的底层实现数组
从以下版本开始:
1.6

arrayOffset

public abstract int arrayOffset()
返回此缓冲区的底层实现数组中第一个缓冲区元素的偏移量 (可选操作)

如果此缓冲区存在底层实现数组,那么缓冲区位置 p 对应于数组索引 p + arrayOffset()

调用此方法前应调用 hasArray 方法,以确保此缓冲区存在可访问的底层实现数组。

返回:
此缓冲区数组中第一个缓冲区元素的偏移量
抛出:
ReadOnlyBufferException - 如果此缓冲区存在底层实现数组,但它是只读的
UnsupportedOperationException - 如果此缓冲区不存在可访问的底层实现数组
从以下版本开始:
1.6

isDirect

public abstract boolean isDirect()
告知此缓冲区是否为 直接缓冲区

返回:
当且仅当此缓冲区为直接缓冲区时返回 true
从以下版本开始:
1.6