Module java.base
Package java.nio

Class MappedByteBuffer

所有已实现的接口:
Comparable<ByteBuffer>

public abstract sealed class MappedByteBuffer extends ByteBuffer
一个直接的字节缓冲区,其内容是文件的内存映射区域。

通过FileChannel.map方法创建映射字节缓冲区。此类扩展了ByteBuffer类,具有特定于内存映射文件区域的操作。

映射字节缓冲区及其表示的文件映射在缓冲区本身被垃圾回收之前保持有效。

映射字节缓冲区的内容可以随时更改,例如,如果映射文件的相应区域的内容由本程序或其他程序更改。此类更改是否发生,以及何时发生,取决于操作系统,因此是未指定的。

映射字节缓冲区的全部或部分内容可能随时变得无法访问,例如,如果映射文件被截断。尝试访问映射字节缓冲区的无法访问区域不会更改缓冲区的内容,并将导致在访问时或稍后抛出未指定的异常。因此,强烈建议采取适当的预防措施,以避免本程序或同时运行的程序操纵映射文件,除非读取或写入文件的内容。

除此之外,映射字节缓冲区的行为与普通的直接字节缓冲区没有任何不同。

自1.4版本起:
  • Method Details

    • isLoaded

      public final boolean isLoaded()
      告知此缓冲区的内容是否驻留在物理内存中。

      返回值为true意味着很可能此缓冲区中的所有数据都驻留在物理内存中,因此可以在不产生任何虚拟内存页错误或I/O操作的情况下访问。返回值为false并不一定意味着缓冲区的内容未驻留在物理内存中。

      返回的值是一个提示,而不是保证,因为在调用此方法返回时,底层操作系统可能已经将缓冲区的一些数据分页出去。

      返回:
      如果此缓冲区的内容很可能驻留在物理内存中,则返回true
    • load

      public final MappedByteBuffer load()
      将此缓冲区的内容加载到物理内存中。

      此方法尽最大努力确保在返回时,此缓冲区的内容驻留在物理内存中。调用此方法可能导致发生一些页面错误和I/O操作。

      返回:
      此缓冲区
    • force

      public final MappedByteBuffer force()
      强制将对此缓冲区内容所做的任何更改写入包含映射文件的存储设备。该区域从此缓冲区中的索引零开始,长度为capacity()字节。调用此方法的行为与调用force(0,capacity())的行为完全相同。

      如果映射到此缓冲区的文件驻留在本地存储设备上,则当此方法返回时,可以保证自创建缓冲区以来对缓冲区所做的所有更改,或自上次调用此方法以来对缓冲区所做的所有更改,都已写入该设备。

      如果文件不驻留在本地设备上,则不提供此类保证。

      如果此缓冲区未以读/写模式映射(FileChannel.MapMode.READ_WRITE),则调用此方法可能不起作用。特别地,对于以只读或私有映射模式映射的缓冲区,该方法不起作用。对于特定于实现的映射模式,此方法可能有或可能没有效果。

      返回:
      此缓冲区
      抛出:
      UncheckedIOException - 如果将缓冲区的内容写回包含映射文件的存储设备时发生I/O错误
    • force

      public final MappedByteBuffer force(int index, int length)
      强制将对此缓冲区内容的区域所做的任何更改写入包含映射文件的存储设备。该区域从此缓冲区中的给定index开始,长度为length字节。

      如果映射到此缓冲区的文件驻留在本地存储设备上,则当此方法返回时,可以保证自创建缓冲区以来对所选区域缓冲区所做的所有更改,或自上次调用此方法以来对所选区域缓冲区所做的所有更改,都已写入该设备。强制操作可以写入超出指定区域的字节,例如,以确保以某种设备特定的粒度传输数据块。

      如果文件不驻留在本地设备上,则不提供此类保证。

      如果此缓冲区未以读/写模式映射(FileChannel.MapMode.READ_WRITE),则调用此方法可能不起作用。特别地,对于以只读或私有映射模式映射的缓冲区,该方法不起作用。对于特定于实现的映射模式,此方法可能有或可能没有效果。

      参数:
      index - 要写回存储的缓冲区区域中第一个字节的索引;必须是非负数且小于capacity()
      length - 区域的长度(以字节为单位);必须是非负数且不大于capacity() - index
      返回:
      此缓冲区
      抛出:
      IndexOutOfBoundsException - 如果索引和长度的前提条件不成立。
      UncheckedIOException - 如果将缓冲区的内容写回包含映射文件的存储设备时发生I/O错误
      自13版本起:
    • position

      public final MappedByteBuffer position(int newPosition)
      设置此缓冲区的位置。如果标记已定义且大于新位置,则将其丢弃。
      覆盖:
      position 在类 ByteBuffer
      参数:
      newPosition - 新的位置值;必须是非负数且不大于当前限制
      返回:
      此缓冲区
      自9版本起:
    • limit

      public final MappedByteBuffer limit(int newLimit)
      设置此缓冲区的限制。如果位置大于新限制,则将其设置为新限制。如果标记已定义且大于新限制,则将其丢弃。
      覆盖:
      limit 在类 ByteBuffer
      参数:
      newLimit - 新的限制值;必须是非负数且不大于此缓冲区的容量
      返回:
      此缓冲区
      自9版本起:
    • mark

      public final MappedByteBuffer mark()
      在其位置设置此缓冲区的标记。
      覆盖:
      mark 在类 ByteBuffer
      返回:
      此缓冲区
      自9版本起:
    • reset

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

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

      覆盖:
      reset 在类 ByteBuffer
      返回:
      此缓冲区
      自9版本起:
    • clear

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

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

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

      此方法实际上不会擦除缓冲区中的数据,但它的命名方式表明它可能会在那种情况下使用。

      覆盖:
      clear 在类 ByteBuffer
      返回:
      此缓冲区
      自9版本起:
    • flip

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

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

          buf.put(magic);    // 在头部添加
          in.read(buf);      // 将数据读入缓冲区的其余部分
          buf.flip();        // 翻转缓冲区
          out.write(buf);    // 将头部+数据写入通道
      

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

      覆盖:
      flip 在类中 ByteBuffer
      返回:
      此缓冲区
      自:
      9
    • rewind

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

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

          out.write(buf);    // 写入剩余数据
          buf.rewind();      // 倒带缓冲区
          buf.get(array);    // 将数据复制到数组中
      
      覆盖:
      rewind 在类中 ByteBuffer
      返回:
      此缓冲区
      自:
      9
    • slice

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

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

      新缓冲区的位置将为零,其容量和限制将为此缓冲区中剩余的字节数,其标记将未定义,其字节顺序将为BIG_ENDIAN。如果此缓冲区是直接的,则新缓冲区也将是直接的;如果此缓冲区是只读的,则新缓冲区也将是只读的。

      通过在返回的缓冲区上调用load()来将字节读入物理内存,或通过在返回的缓冲区上调用force()将字节写入存储设备,将仅对返回的缓冲区表示的此缓冲区的子范围[position(),limit())进行操作。

      指定者:
      slice 在类中 ByteBuffer
      返回:
      新的字节缓冲区
      另请参阅:
    • slice

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

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

      新缓冲区的位置将为零,其容量和限制将为length,其标记将未定义,其字节顺序将为BIG_ENDIAN。如果此缓冲区是直接的,则新缓冲区也将是直接的;如果此缓冲区是只读的,则新缓冲区也将是只读的。

      通过在返回的缓冲区上调用load()来将字节读入物理内存,或通过在返回的缓冲区上调用force()将字节写入存储设备,将仅对返回的缓冲区表示的此缓冲区的子范围[index,index+length)进行操作,其中假定indexlength满足前提条件。

      指定者:
      slice 在类中 ByteBuffer
      参数:
      index - 新缓冲区内容将从中开始的此缓冲区中的位置;必须为非负且不大于limit()
      length - 新缓冲区将包含的元素数;必须为非负且不大于limit() - index
      返回:
      新缓冲区
    • duplicate

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

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

      新缓冲区的容量、限制、位置和标记值将与此缓冲区相同,其字节顺序将为BIG_ENDIAN。如果此缓冲区是直接的,则新缓冲区也将是直接的;如果此缓冲区是只读的,则新缓冲区也将是只读的。

      指定者:
      duplicate 在类中 ByteBuffer
      返回:
      新的字节缓冲区
    • compact

      public abstract MappedByteBuffer compact()
      压缩此缓冲区  (可选操作)

      缓冲区当前位置和其限制之间(如果有)的字节将被复制到缓冲区的开头。也就是说,索引p = position()处的字节将被复制到索引零处,索引p + 1的字节将被复制到索引一处,依此类推,直到索引limit() - 1的字节被复制到索引n = limit() - 1 - p处。然后,缓冲区的位置设置为n+1,其限制设置为其容量。如果定义了标记,则将其丢弃。

      缓冲区的位置设置为复制的字节数,而不是零,以便可以立即在此方法调用之后调用另一个相对put方法。

      在从缓冲区写入数据后调用此方法,以防写入不完整。例如,以下循环通过缓冲区buf将字节从一个通道复制到另一个通道:

          buf.clear();          // 准备缓冲区以供使用
          while (in.read(buf) >= 0 || buf.position != 0) {
              buf.flip();
              out.write(buf);
              buf.compact();    // 以防部分写入
          }
      
      指定者:
      compact 在类中 ByteBuffer
      返回:
      此缓冲区