java.nio

异常
java.lang.Object
  继承者 java.nio.Buffer
      继承者 java.nio.ByteBuffer
所有已实现的接口:
Comparable< ByteBuffer>
直接已知子类:
MappedByteBuffer

public abstract class ByteBuffer
     
extends Buffer
implements Comparable< ByteBuffer>

字节缓冲区。

此类针对字节缓冲区定义了以下六类操作:

  • 读写单个字节的绝对和相对 getput 方法;

  • 将此缓冲区的连续字节序列传输到数组中的相对批量 get 方法;

  • 将 byte 数组或其他字节缓冲区中的连续字节序列传输到此缓冲区的相对批量 put 方法;

  • 读写其他基本类型值,并按照特定的字节顺序在字节序列之间转换这些值的绝对和相对 getput 方法;

  • 创建视图缓冲区 的方法,这些方法允许将字节缓冲区视为包含其他基本类型值的缓冲区;

  • 对字节缓冲区进行 compactingduplicatingslicing 的方法。

字节缓冲区可以通过 allocation 方法创建,此方法为该缓冲区的内容分配空间,或通过 wrapping 方法将现有的 byte 数组包装到缓冲区中来创建。

直接 非直接缓冲区

字节缓冲区要么是直接的,要么是非直接的。如果为直接字节缓冲区,则 Java 虚拟机会尽最大努力直接在此缓冲区上执行本机 I/O 操作。也就是说,在每次调用基础操作系统的一个本机 I/O 操作之前(或之后),虚拟机都会尽量避免将缓冲区的内容复制到中间缓冲区中(或从中间缓冲区中复制内容)。

直接字节缓冲区可以通过调用此类的 allocateDirect 工厂方法来创建。此方法返回的缓冲区进行分配和取消分配所需成本通常高于非直接缓冲区。直接缓冲区的内容可以驻留在常规的垃圾回收堆之外,因此,它们对应用程序的内存需求量造成的影响可能并不明显。所以,建议将直接缓冲区主要分配给那些易受基础系统的本机 I/O 操作影响的大型、持久的缓冲区。一般情况下,最好仅在直接缓冲区能在程序性能方面带来明显好处时分配它们。

直接字节缓冲区还可以通过 mapping 将文件区域直接映射到内存中来创建。Java 平台的实现有助于通过 JNI 从本机代码创建直接字节缓冲区。如果以上这些缓冲区中的某个缓冲区实例指的是不可访问的内存区域,则试图访问该区域不会更改该缓冲区的内容,并且将会在访问期间或稍后的某个时间导致抛出不确定的异常。

字节缓冲区是直接缓冲区还是非直接缓冲区可通过调用其 isDirect 方法来确定。提供此方法是为了能够在性能关键型代码中执行显式缓冲区管理。

访问二进制数据

此类定义了除 boolean 之外,读写所有其他基本类型值的方法。这些基本值可以根据缓冲区的当前字节顺序与字节序列互相进行转换,并可以通过 order 方法获取和修改。特定的字节顺序由 ByteOrder 类的实例表示。字节缓冲区的初始顺序始终是 BIG_ENDIAN

为了访问异类二进制数据(即其他类型的值的序列),此类还针对每种类型定义了一系列绝对和相对的 getput 方法。例如,对于 32 位浮点值,此类定义了以下方法:

 float  getFloat()
 float  getFloat(int index)
  void  putFloat(float f)
  void  putFloat(int index, float f)

并针对 charshortintlongdouble 等类型定义了相应的方法。绝对 getput 方法的 index 参数是根据字节定义的,而不是根据所读写的类型定义的。

为了访问同类二进制数据(即相同类型的值的序列),此类还定义了可以为指定类型的缓冲区创建视图 的方法。视图缓冲区 只是其内容受该字节缓冲区支持的另一种缓冲区。字节缓冲区内容的更改在视图缓冲区中是可见的,反之亦然;这两种缓冲区的位置、限制和标记值都是独立的。例如,asFloatBuffer 方法将创建 FloatBuffer 类的一个实例,该类受在其上调用该方法的字节缓冲区的支持。该类将为 charshortintlongdouble 等类型定义相应的视图创建方法。

与上述特定于类型的 getput 方法系列相比,视图缓冲区有以下三大主要优势:

  • 视图缓冲区不是根据字节进行索引,而是根据其特定于类型的值的大小进行索引;

  • 视图缓冲区提供了相对批量 getput 方法,这些方法可在缓冲区和数组或相同类型的其他缓冲区之间传输值的连续序列;

  • 视图缓冲区可能更高效,这是因为,当且仅当其支持的字节缓冲区为直接缓冲区时它才是直接缓冲区。

视图缓冲区的字节顺序固定为创建该视图时其字节缓冲区的字节顺序。

调用的链接

指定此类中的方法(它们不返回其他值),以返回这些方法被调用时所在的缓冲区。这允许对方法调用进行链接。 例如,语句序列

 bb.putInt(0xCAFEBABE);
 bb.putShort(3);
 bb.putShort(45);
可以由以下单个语句替换
 bb.putInt(0xCAFEBABE).putShort(3).putShort(45);

从以下版本开始:
1.4

方法摘要
static ByteBuffer allocate(int capacity)
          分配一个新的字节缓冲区。
static ByteBuffer allocateDirect(int capacity)
          分配新的直接字节缓冲区。
 byte[] array()
          返回实现此缓冲区的 byte 数组(可选操作)
 int arrayOffset()
          返回此缓冲区中的第一个元素在缓冲区的底层实现数组中的偏移量(可选操作)
abstract  CharBuffer asCharBuffer()
          创建此字节缓冲区的视图,作为 char 缓冲区。
abstract  DoubleBuffer asDoubleBuffer()
          创建此字节缓冲区的视图,作为 double 缓冲区。
abstract  FloatBuffer asFloatBuffer()
          创建此字节缓冲区的视图,作为 float 缓冲区。
abstract  IntBuffer asIntBuffer()
          创建此字节缓冲区的视图,作为 int 缓冲区。
abstract  LongBuffer asLongBuffer()
          创建此字节缓冲区的视图,作为 long 缓冲区。
abstract  ByteBuffer asReadOnlyBuffer()
          创建共享此缓冲区内容的新的只读字节缓冲区。
abstract  ShortBuffer asShortBuffer()
          创建此字节缓冲区的视图,作为 short 缓冲区。
abstract  ByteBuffer compact()
          压缩此缓冲区(可选操作)
 int compareTo(ByteBuffer that)
          将此缓冲区与另一个缓冲区进行比较。
abstract  ByteBuffer duplicate()
          创建共享此缓冲区内容的新的字节缓冲区。
 boolean equals(Object ob)
          判断此缓冲区是否与另一个对象相同。
abstract  byte get()
          相对 get 方法。
 ByteBuffer get(byte[] dst)
          相对批量 get 方法。
 ByteBuffer get(byte[] dst, int offset, int length)
          相对批量 get 方法。
abstract  byte get(int index)
          绝对 get 方法。
abstract  char getChar()
          用于读取 char 值的相对 get 方法。
abstract  char getChar(int index)
          用于读取 char 值的绝对 get 方法。
abstract  double getDouble()
          用于读取 double 值的相对 get 方法。
abstract  double getDouble(int index)
          用于读取 double 值的绝对 get 方法。
abstract  float getFloat()
          用于读取 float 值的相对 get 方法。
abstract  float getFloat(int index)
          用于读取 float 值的绝对 get 方法。
abstract  int getInt()
          用于读取 int 值的相对 get 方法。
abstract  int getInt(int index)
          用于读取 int 值的绝对 get 方法。
abstract  long getLong()
          用于读取 long 值的相对 get 方法。
abstract  long getLong(int index)
          用于读取 long 值的绝对 get 方法。
abstract  short getShort()
          用于读取 short 值的相对 get 方法。
abstract  short getShort(int index)
          用于读取 short 值的绝对 get 方法。
 boolean hasArray()
          判断是否可通过一个可访问的 byte 数组实现此缓冲区。
 int hashCode()
          返回此缓冲区的当前哈希码。
abstract  boolean isDirect()
          判断此字节缓冲区是否为直接的。
 ByteOrder order()
          获取此缓冲区的字节顺序。
 ByteBuffer order(ByteOrder bo)
          修改此缓冲区的字节顺序。
abstract  ByteBuffer put(byte b)
          相对 put 方法(可选操作)
 ByteBuffer put(byte[] src)
          相对批量 put 方法(可选操作)
 ByteBuffer put(byte[] src, int offset, int length)
          相对批量 put 方法(可选操作)
 ByteBuffer put(ByteBuffer src)
          相对批量 put 方法(可选操作)
abstract  ByteBuffer put(int index, byte b)
          绝对 put 方法(可选操作)
abstract  ByteBuffer putChar(char value)
          用来写入 char 值的相对 put 方法(可选操作)
abstract  ByteBuffer putChar(int index, char value)
          用于写入 char 值的绝对 put 方法(可选操作)
abstract  ByteBuffer putDouble(double value)
          用于写入 double 值的相对 put 方法(可选操作)
abstract  ByteBuffer putDouble(int index, double value)
          用于写入 double 值的绝对 put 方法(可选操作)
abstract  ByteBuffer putFloat(float value)
          用于写入 float 值的相对 put 方法(可选操作)
abstract  ByteBuffer putFloat(int index, float value)
          用于写入 float 值的绝对 put 方法(可选操作)
abstract  ByteBuffer putInt(int value)
          用于写入 int 值的相对 put 方法(可选操作)
abstract  ByteBuffer putInt(int index, int value)
          用于写入 int 值的绝对 put 方法(可选操作)
abstract  ByteBuffer putLong(int index, long value)
          用于写入 long 值的绝对 put 方法(可选操作)
abstract  ByteBuffer putLong(long value)
          用于写入 long 值(可先操作) 的相对 put 方法。
abstract  ByteBuffer putShort(int index, short value)
          用于写入 short 值的绝对 put 方法(可选操作)
abstract  ByteBuffer putShort(short value)
          用于写入 short 值的相对 put 方法(可选操作)
abstract  ByteBuffer slice()
          创建新的字节缓冲区,其内容是此缓冲区内容的共享子序列。
 String toString()
          返回汇总了此缓冲区状态的字符串。
static ByteBuffer wrap(byte[] array)
          将 byte 数组包装到缓冲区中。
static ByteBuffer wrap(byte[] array, int offset, int length)
          将 byte 数组包装到缓冲区中。
 
从类 java.nio.Buffer 继承的方法
capacity, clear, flip, hasRemaining, isReadOnly, limit, limit, mark, position, position, remaining, reset, rewind
 
从类 java.lang.Object 继承的方法
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

方法详细信息

allocateDirect

public static ByteBuffer allocateDirect(int capacity)
分配新的直接字节缓冲区。

新缓冲区的位置将为零,其界限将为其容量,其标记是不确定的。无论它是否具有底层实现数组,其标记都是不确定的。

参数:
capacity - 新缓冲区的容量,以字节为单位
返回:
新的字节缓冲区
抛出:
IllegalArgumentException - 如果 capacity 为负整数

allocate

public static ByteBuffer allocate(int capacity)
分配一个新的字节缓冲区。

新缓冲区的位置将为零,其界限将为其容量,其标记是不确定的。它将具有一个底层实现数组,且其 数组偏移量将为零。

参数:
capacity - 新缓冲区的容量,以字节为单位
返回:
新的字节缓冲区
抛出:
IllegalArgumentException - 如果 capacity 为负整数

wrap

public static ByteBuffer wrap(byte[] array,
                              int offset,
                              int length)
将 byte 数组包装到缓冲区中。

新的缓冲区将由给定的 byte 数组支持;也就是说,缓冲区修改将导致数组修改,反之亦然。新缓冲区的容量将为 array.length,其位置将为 offset,其界限将为 offset + length,其标记是不确定的。其底层实现数组将为给定数组,并且其数组偏移量将为零。

参数:
array - 支持新缓冲区的数组
offset - 要使用的子数组的偏移量;必须为非负且不大于 array.length。将新缓冲区的位置设置为此值。
length - 要使用的子数组的长度;必须为非负且不大于 array.length - offset。将新缓冲区的界限设置为 offset + length
返回:
新的字节缓冲区
抛出:
IndexOutOfBoundsException - 如果关于 offsetlength 参数的前提不成立

wrap

public static ByteBuffer wrap(byte[] array)
将 byte 数组包装到缓冲区中。

新的缓冲区将由给定的 byte 数组支持;也就是说,缓冲区修改将导致数组修改,反之亦然。新缓冲区的容量和界限将为 array.length,其位置将为零,其标记是不确定的。其底层实现数组将为给定数组,并且其数组偏移量将为零。

参数:
array - 实现此缓冲区的数组
返回:
新的字节缓冲区

slice

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

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

新缓冲区的位置将为零,其容量和界限将为此缓冲区中所剩余的字节数量,其标记是不确定的。当且仅当此缓冲区为直接时,新缓冲区才是直接的,当且仅当此缓冲区为只读时,新缓冲区才是只读的。

返回:
新的字节缓冲区

duplicate

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

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

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

返回:
新的字节缓冲区

asReadOnlyBuffer

public abstract ByteBuffer asReadOnlyBuffer()
创建共享此缓冲区内容的新的只读字节缓冲区。

新缓冲区的内容将为此缓冲区的内容。此缓冲区内容的更改在新缓冲区中是可见的,但新缓冲区将是只读的并且不允许修改共享内容。两个缓冲区的位置、界限和标记值是相互独立的。

新缓冲区的容量、界限、位置和标记值将与此缓冲区相同。

如果此缓冲区本身是只读的,则此方法与 duplicate 方法完全相同。

返回:
新的只读字节缓冲区

get

public abstract byte get()
相对 get 方法。读取此缓冲区当前位置的字节,然后该位置递增。

返回:
缓冲区当前位置的字节
抛出:
BufferUnderflowException - 如果该缓冲区的当前位置不小于其界限

put

public abstract ByteBuffer put(byte b)
相对 put 方法 (可选操作)

将给定的字节写入此缓冲区的当前位置,然后该位置递增。

参数:
b - 要写入的字节
返回:
此缓冲区
抛出:
BufferOverflowException - 如果此缓冲区的当前位置不小于其界限
ReadOnlyBufferException - 如果此缓冲区是只读缓冲区

get

public abstract byte get(int index)
绝对 get 方法。读取指定索引处的字节。

参数:
index - 将从中读取该字节的索引
返回:
给定索引处的字节
抛出:
IndexOutOfBoundsException - 如果 index 为负或不小于缓冲区界限

put

public abstract ByteBuffer put(int index,
                               byte b)
绝对 put 方法 (可选操作)

将给定字节写入此缓冲区的给定索引处。

参数:
index - 将在该位置写入字节的索引
b - 要写入的字节值
返回:
此缓冲区
抛出:
IndexOutOfBoundsException - 如果 index 为负或不小于缓冲区界限
ReadOnlyBufferException - 如果此缓冲区是只读缓冲区

get

public ByteBuffer get(byte[] dst,
                      int offset,
                      int length)
相对批量 get 方法。

此方法将此缓冲区的字节传输到给定的目标数组中。如果此缓冲中剩余的字节少于满足请求所需的字节(即如果 length > remaining()),则不传输字节且抛出 BufferUnderflowException

否则,此方法将此缓冲区中的 length 个字节复制到给定数组中,从此缓冲区的当前位置和数组中的给定偏移量位置开始复制。然后此缓冲区的位置将增加 length

换句话说,调用此方法的形式为 src.get(dst, off, len),效果与以下循环语句完全相同:

     for (int i = off; i < off + len; i++)
         dst[i] = src.get(); 
区别在于它首先检查此缓冲区中是否具有足够的字节,这样可能效率更高。

参数:
dst - 向其中写入字节的数组
offset - 要写入的第一个字节在数组中的偏移量;必须为非负且不大于 dst.length
length - 要写入到给定数组中的字节的最大数量;必须为非负且不大于 dst.length - offset
返回:
此缓冲区
抛出:
BufferUnderflowException - 如果此缓冲区中的剩余字节少于 length
IndexOutOfBoundsException - 如果关于 offsetlength 参数的前提不成立

get

public ByteBuffer get(byte[] dst)
相对批量 get 方法。

此方法将此缓冲区的字节传输到给定的目标数组中。调用此方法的形式为 src.get(a),该调用与以下调用完全相同:

     src.get(a, 0, a.length) 

返回:
此缓冲区
抛出:
BufferUnderflowException - 如果此缓冲区中的剩余字节少于 length

put

public ByteBuffer put(ByteBuffer src)
相对批量 put 方法 (可选操作)

此方法将给定源缓冲区中的剩余字节传输到此缓冲区中。如果源缓冲区中的剩余字节多于此缓冲区中的剩余字节,即如果 src.remaining() > remaining(),则不传输字节且抛出 BufferOverflowException

否则,此方法将给定缓冲区中的 n = src.remaining() 个字节复制到此缓冲区中,从每个缓冲区的当前位置开始复制。然后这两个缓冲区的位置都增加 n

换句话说,调用此方法的形式为 dst.put(src),效果与以下循环语句完全相同:

     while (src.hasRemaining())
         dst.put(src.get()); 
区别在于它首先检查此缓冲区中是否有足够空间,这样可能效率更高。

参数:
src - 要从中读取字节的源缓冲区;不能为此缓冲区
返回:
此缓冲区
抛出:
BufferOverflowException - 如果此缓冲区没有足够的空间来容纳源缓冲区中剩余的字节
IllegalArgumentException - 如果源缓冲区是此缓冲区
ReadOnlyBufferException - 如果此缓冲区是只读缓冲区

put

public ByteBuffer put(byte[] src,
                      int offset,
                      int length)
相对批量 put 方法 (可选操作)

此方法将把给定源数组中的字节字传输到此缓冲区中。如果要从该数组中复制的字节多于此缓冲区中的剩余字节,即如果 length > remaining()),则不传输字节且将抛出 BufferOverflowException

否则,此方法将给定数组中的 length 个字节复制到此缓冲区中,从数组中给定偏移量位置和此缓冲区的当前位置开始复制。然后此缓冲区的位置将增加 length

换句话说,调用此方法的形式为 dst.put(src, off, len),效果与以下循环语句完全相同:

     for (int i = off; i < off + len; i++)
         dst.put(a[i]); 
区别在于它首先检查此缓冲区中是否有足够空间,这样可能效率更高。

参数:
src - 要从中读取字节的数组
offset - 要读取的第一个字节在数组中的偏移量;必须为非负且不大于 array.length
length - 要从给定数组读取的字节的数量;必须为非负且不大于 array.length - offset
返回:
此缓冲区
抛出:
BufferOverflowException - 如果此缓冲区没有足够空间
IndexOutOfBoundsException - 如果关于 offsetlength 参数的前提不成立
ReadOnlyBufferException - 如果此缓冲区是只读缓冲区

put

public final ByteBuffer put(byte[] src)
相对批量 put 方法 (可选操作)

此方法将给定的源 byte 数组的所有内容传输到此缓冲区中。调用此方法的形式为 dst.put(a),该调用与以下调用完全相同:

     dst.put(a, 0, a.length) 

返回:
此缓冲区
抛出:
BufferOverflowException - 如果此缓冲区没有足够空间
ReadOnlyBufferException - 如果此缓冲区是只读缓冲区

hasArray

public final boolean hasArray()
判断是否可通过一个可访问的 byte 数组实现此缓冲区。

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

指定者:
Buffer 中的 hasArray
返回:
当且仅当存在实现此缓冲区的数组,并且此缓冲区不是只读缓冲区时,返回 true

array

public final byte[] array()
返回实现此缓冲区的 byte 数组 (可选操作)

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

调用此方法之前要调用 hasArray 方法,以确保此缓冲区具有可访问的底层实现数组。

指定者:
Buffer 中的 array
返回:
实现此缓冲区的数组
抛出:
ReadOnlyBufferException - 如果存在实现此缓冲区的数组,但缓冲区是只读的
UnsupportedOperationException - 如果不存在某个可访问的数组实现此缓冲区

arrayOffset

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

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

调用此方法之前要调用 hasArray 方法,以确保此缓冲区具有可访问的底层实现数组。

指定者:
Buffer 中的 arrayOffset
返回:
此缓冲区的第一个元素在缓冲区数组中的偏移量
抛出:
ReadOnlyBufferException - 如果存在实现此缓冲区的数组,但缓冲区是只读的
UnsupportedOperationException - 如果不存在某个可访问的数组实现此缓冲区

compact

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

将缓冲区的当前位置和界限之间的字节(如果有)复制到缓冲区的开始处。即将索引 p = position() 处的字节复制到索引 0 处,将索引 p + 1 处的字节复制到索引 1 处,依此类推,直到将索引 limit() - 1 处的字节复制到索引 n = limit() - 1 - p 处。然后将缓冲区的位置设置为 n+1,并将其界限设置为其容量。如果已定义了标记,则丢弃它。

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