模块 java.base
 java.nio

类 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
特定原始类型数据的容器。

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

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

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

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

每个非布尔原始类型都有此类的一个子类。

传输数据

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

相对的操作从当前位置开始读取或写入一个或多个元素,然后按传输的元素数增加位置。如果请求的转账超过限额,则亲属get操作抛出一个BufferUnderflowException 和一个亲戚put操作抛出一个 BufferOverflowException ;在任何一种情况下,都不会传输任何数据。

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

当然,也可以通过适当通道的 I/O 操作将数据传入或传出缓冲区,这些操作始终与当前位置相关。

标记和重置

缓冲区的mark是调用 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);
密封类层次结构图:
Sealed class hierarchy graph for BufferSealed class hierarchy graph for Buffer
自从:
1.4
  • 方法总结

    修饰符和类型
    方法
    描述
    abstract Object
    返回支持此缓冲区的数组(可选操作).
    abstract int
    返回缓冲区第一个元素在此缓冲区的后备数组中的偏移量(可选操作).
    final int
    返回此缓冲区的容量。
    清除此缓冲区。
    abstract Buffer
    创建一个共享此缓冲区内容的新缓冲区。
    flip()
    翻转此缓冲区。
    abstract boolean
    告知此缓冲区是否由可访问数组支持。
    final boolean
    告诉当前位置和限制之间是否有任何元素。
    abstract boolean
    判断此缓冲区是否为 直接的
    abstract boolean
    告知此缓冲区是否为只读。
    final int
    返回此缓冲区的限制。
    limit(int newLimit)
    设置此缓冲区的限制。
    mark()
    在其位置设置此缓冲区的标记。
    final int
    返回此缓冲区的位置。
    position(int newPosition)
    设置此缓冲区的位置。
    final int
    返回当前位置和限制之间的元素数。
    将此缓冲区的位置重置为先前标记的位置。
    倒带此缓冲区。
    abstract Buffer
    创建一个新缓冲区,其内容是此缓冲区内容的共享子序列。
    abstract Buffer
    slice(int index, int length)
    创建一个新缓冲区,其内容是此缓冲区内容的共享子序列。

    在类 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 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();   // Prepare buffer for reading
       in.read(buf);  // Read data

      这种方法实际上并没有擦除缓冲区中的数据,但它的命名就好像它确实擦除一样,因为它最常用于可能是这种情况的情况。

      返回:
      这个缓冲区
    • flip

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

      经过一系列通道读取或put操作,调用此方法来准备一系列通道写入或相关get操作。例如:

       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 Buffer  rewind()
      倒带此缓冲区。位置设置为零,标记被丢弃。

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

       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,则可以安全地调用 array arrayOffset 方法。

      返回:
      true 当且仅当此缓冲区由数组支持并且不是只读的
      自从:
      1.6
    • array

      public abstract Object  array()
      返回支持此缓冲区的数组(可选操作).

      此方法旨在允许将支持数组的缓冲区更有效地传递给本机代码。具体的子类为此方法提供更强类型的返回值。

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

      在调用此方法之前调用 hasArray 方法,以确保此缓冲区具有可访问的后备数组。

      返回:
      支持此缓冲区的数组
      抛出:
      ReadOnlyBufferException - 如果此缓冲区由数组支持但为只读
      UnsupportedOperationException - 如果此缓冲区不受可访问数组的支持
      自从:
      1.6
    • arrayOffset

      public abstract int arrayOffset()
      返回缓冲区第一个元素在此缓冲区的后备数组中的偏移量(可选操作).

      如果此缓冲区由数组支持,则缓冲区位置p对应数组索引parrayOffset()

      在调用此方法之前调用 hasArray 方法,以确保此缓冲区具有可访问的后备数组。

      返回:
      缓冲区第一个元素在此缓冲区数组中的偏移量
      抛出:
      ReadOnlyBufferException - 如果此缓冲区由数组支持但为只读
      UnsupportedOperationException - 如果此缓冲区不受可访问数组的支持
      自从:
      1.6
    • isDirect

      public abstract boolean isDirect()
      判断此缓冲区是否为 直接的
      返回:
      true 当且仅当此缓冲区是直接的
      自从:
      1.6
    • slice

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

      新缓冲区的内容将从该缓冲区的当前位置开始。对此缓冲区内容的更改将在新缓冲区中可见,反之亦然;两个缓冲区的位置、限制和标记值将是独立的。

      新缓冲区的位置将为零,其容量和限制将为该缓冲区中剩余的元素数,其标记将未定义。当且仅当此缓冲区是直接的时,新缓冲区将是直接的,并且当且仅当此缓冲区是只读的时,它将是只读的。

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

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

      新缓冲区的内容将从该缓冲区中的位置 index 开始,并将包含 length 个元素。对此缓冲区内容的更改将在新缓冲区中可见,反之亦然;两个缓冲区的位置、限制和标记值将是独立的。

      新缓冲区的位置将为零,其容量和限制将为 length ,其标记将未定义。当且仅当此缓冲区是直接的时,新缓冲区将是直接的,并且当且仅当此缓冲区是只读的时,它将是只读的。

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

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

      新缓冲区的内容将是该缓冲区的内容。对此缓冲区内容的更改将在新缓冲区中可见,反之亦然;两个缓冲区的位置、限制和标记值将是独立的。

      新缓冲区的容量、限制、位置和标记值将与该缓冲区的相同。当且仅当此缓冲区是直接的时,新缓冲区将是直接的,并且当且仅当此缓冲区是只读的时,它将是只读的。

      返回:
      新缓冲区
      自从:
      9