Module java.base
Package java.nio

Class Buffer

java.lang.Object
java.nio.Buffer
直接已知的子类:
ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer

public abstract sealed class Buffer extends Object permits ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer
特定原始类型数据的容器。

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

缓冲区的容量是它包含的元素数量。缓冲区的容量永远不会是负数,也永远不会改变。

缓冲区的限制是不应读取或写入的第一个元素的索引。缓冲区的限制永远不会是负数,也永远不会大于其容量。

缓冲区的位置是要读取或写入的下一个元素的索引。缓冲区的位置永远不会是负数,也永远不会大于其限制。

对于每种非布尔原始类型,此类都有一个子类。

传输数据

此类的每个子类定义了两类getput操作:

相对操作从当前位置开始读取或写入一个或多个元素,然后将位置递增传输的元素数量。如果请求的传输超过限制,则相对get操作会抛出一个BufferUnderflowException,而相对put操作会抛出一个BufferOverflowException;在任何情况下,都不会传输数据。

绝对操作采用显式元素索引,不影响位置。如果索引参数超过限制,则绝对getput操作会抛出一个IndexOutOfBoundsException

当然,数据也可以通过适当通道的I/O操作传输到缓冲区或从缓冲区中传出,这些操作始终相对于当前位置。

标记和重置

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

不变性

对于标记、位置、限制和容量值,以下不变性成立:

0 <= mark <= position <= limit <= capacity

新创建的缓冲区始终具有零位置和未定义的标记。初始限制可以是零,也可以是取决于缓冲区类型和构造方式的其他值。新分配的缓冲区的每个元素都初始化为零。

附加操作

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

  • clear()使缓冲区准备好进行新的通道读取序列或相对put操作:它将限制设置为容量,将位置设置为零。

  • flip()使缓冲区准备好进行新的通道写入序列或相对get操作:它将限制设置为当前位置,然后将位置设置为零。

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

  • slice()slice(index,length)方法创建缓冲区的子序列:它们保持限制和位置不变。

  • duplicate()创建缓冲区的浅拷贝:它保持限制和位置不变。

只读缓冲区

每个缓冲区都是可读的,但并非每个缓冲区都是可写的。每个缓冲区类的变异方法被指定为在只读缓冲区上调用时会抛出一个ReadOnlyBufferException可选操作。只读缓冲区不允许更改其内容,但其标记、位置和限制值是可变的。可以通过调用其isReadOnly方法来确定缓冲区是否为只读。

线程安全

缓冲区不适合多个并发线程使用。如果一个缓冲区将被多个线程使用,则应通过适当的同步来控制对缓冲区的访问。

调用链接

此类中没有其他返回值的方法被指定为返回调用它们的缓冲区。这允许方法调用被链接;例如,以下语句序列

    b.flip();
    b.position(23);
    b.limit(42);
可以被替换为单个更紧凑的语句
    b.flip().position(23).limit(42);
封闭类层次结构图:
Buffer的封闭类层次结构图Buffer的封闭类层次结构图
自1.4版本起:
1.4
  • Method Summary

    Modifier and Type
    Method
    Description
    abstract Object
    array()
    返回支持此缓冲区的数组  (可选操作)
    abstract int
    返回此缓冲区的支持数组中缓冲区的第一个元素的偏移量  (可选操作)
    final int
    返回此缓冲区的容量。
    clear()
    清除此缓冲区。
    abstract Buffer
    创建一个共享此缓冲区内容的新缓冲区。
    flip()
    翻转此缓冲区。
    abstract boolean
    告诉此缓冲区是否由可访问的数组支持。
    final boolean
    告诉当前位置和限制之间是否有任何元素。
    abstract boolean
    告诉此缓冲区是否为直接的。
    abstract boolean
    告诉此缓冲区是否为只读的。
    final int
    limit()
    返回此缓冲区的限制。
    limit(int newLimit)
    设置此缓冲区的限制。
    mark()
    在其位置设置此缓冲区的标记。
    final int
    返回此缓冲区的位置。
    position(int newPosition)
    设置此缓冲区的位置。
    final int
    返回当前位置和限制之间的元素数量。
    reset()
    将此缓冲区的位置重置为先前标记的位置。
    rewind()
    倒带此缓冲区。
    abstract Buffer
    slice()
    创建一个新缓冲区,其内容是此缓冲区内容的共享子序列。
    abstract Buffer
    slice(int index, int length)
    创建一个新缓冲区,其内容是此缓冲区内容的共享子序列。

    Methods declared in class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • capacity

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

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

      public Buffer position(int newPosition)
      设置此缓冲区的位置。如果标记已定义且大于新位置,则将其丢弃。
      参数:
      newPosition - 新位置值;必须为非负且不大于当前限制
      返回:
      此缓冲区
      抛出:
      IllegalArgumentException - 如果对newPosition的前提条件不成立
    • limit

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

      public Buffer limit(int newLimit)
      设置此缓冲区的限制。如果位置大于新限制,则将其设置为新限制。如果标记已定义且大于新限制,则将其丢弃。
      参数:
      newLimit - 新限制值;必须为非负且不大于此缓冲区的容量
      返回:
      此缓冲区
      抛出:
      IllegalArgumentException - 如果对newLimit的前提条件不成立
    • mark

      public Buffer mark()
      在其位置设置此缓冲区的标记。
      返回:
      此缓冲区
    • reset

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

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

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

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

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

          buf.clear();     // 准备缓冲区以供读取
          in.read(buf);    // 读取数据
      

      此方法实际上不会擦除缓冲区中的数据,但它被命名为这样,因为它在大多数情况下将用于可能擦除数据的情况。

      返回:
      此缓冲区
    • flip

      public Buffer flip()
      翻转此缓冲区。限制设置为当前位置,然后位置设置为零。如果定义了标记,则将其丢弃。

      在一系列通道读取或put操作之后,调用此方法准备进行一系列通道写入或相对get操作。例如:

          buf.put(magic);    // 在前面添加标头
          in.read(buf);      // 将数据读入缓冲区的其余部分
          buf.flip();        // 翻转缓冲区
          out.write(buf);    // 将标头+数据写入通道
      
      compact方法一起使用,用于在不同位置之间传输数据。

      返回:
      此缓冲区
    • rewind

      public Buffer rewind()
      倒带此缓冲区。位置设置为零,标记被丢弃。

      在一系列通道写入或get操作之前调用此方法,假设限制已经适当设置。例如:

          out.write(buf);    // 写入剩余数据
          buf.rewind();      // 倒带缓冲区
          buf.get(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()
      告诉此缓冲区是否为direct
      返回:
      如果且仅如果此缓冲区为直接缓冲区,则返回true
      自:
      1.6
    • slice

      public abstract Buffer slice()
      创建一个新的缓冲区,其内容是此缓冲区内容的共享子序列。

      返回:
      新缓冲区
      自:
      9
    • slice

      public abstract Buffer slice(int index, int length)
      创建一个新的缓冲区,其内容是此缓冲区内容的共享子序列。 index开始,并包含 length个元素。对此缓冲区内容的更改将在新缓冲区中可见,反之亦然;两个缓冲区的位置、限制和标记值将是独立的。

      length,其标记将未定义。如果且仅如果此缓冲区为直接缓冲区,则新缓冲区将是直接缓冲区,如果且仅如果此缓冲区为只读,则新缓冲区将是只读的。

      参数:
      index - 新缓冲区内容将从此缓冲区中的位置index开始;必须为非负且不大于limit()
      length - 新缓冲区将包含的元素数量;必须为非负且不大于limit() - index
      返回:
      新缓冲区
      抛出:
      IndexOutOfBoundsException - 如果index为负或大于limit()length为负,或length > limit() - index
      自:
      13
    • duplicate

      public abstract Buffer duplicate()
      创建一个共享此缓冲区内容的新缓冲区。

      返回:
      新缓冲区
      自:
      9