所有基本类型(除布尔)都有相应缓冲区,但字节缓冲区有自己的独特之处。字节是操作系统以及IO使用的基本类型。当在JVM和操作系统间传递数据时,将其他的数据类型拆分成他们的字节是十分必要的。
package java.nio;
public abstract class ByteBuffer extends Buffer
implements Comparable
{
public static ByteBuffer allocate (int capacity)
public static ByteBuffer allocateDirect (int capacity)
public abstract boolean isDirect( );
public static ByteBuffer wrap (byte[] array, int offset, int length)
public static ByteBuffer wrap (byte[] array)
public abstract ByteBuffer duplicate( );
public abstract ByteBuffer asReadOnlyBuffer( );
public abstract ByteBuffer slice( );
public final boolean hasArray( )
public final byte [] array( )
public final int arrayOffset( )
public abstract byte get( );
public abstract byte get (int index);
public ByteBuffer get (byte[] dst, int offset, int length)
public ByteBuffer get (byte[] dst, int offset, int length)
public abstract ByteBuffer put (byte b);
public abstract ByteBuffer put (int index, byte b);
public ByteBuffer put (ByteBuffer src)
public ByteBuffer put (byte[] src, int offset, int length)
public final ByteBuffer put (byte[] src)
public final ByteOrde r order( )
public final ByteBuffer order (ByteOrder bo)
public abstract CharBuffer asCharBuffer( );
public abstract ShortBuffer asShortBuffer( );
public abstract IntBuffer asIntBuffer( );
public abstract LongBuffer asLongBuffer( );
public abstract FloatBuffer asFloatBuffer( );
public abstract DoubleBuffer asDoubleBuffer( );
public abstract char getChar( );
public abstract char getChar (int index);
public abstract ByteBuffer putChar (char value);
public abstract ByteBuffer putChar (int index, char value);
public abstract short getShort( );
public abstract short getShort (int index);
public abstract ByteBuffer putShort (short value);
public abstract ByteBuffer putShort (int index, short value);
public abstract int getInt( );
public abstract int getInt (int index);
public abstract ByteBuffer putInt (int value);
public abstract ByteBuffer putInt (int index, int value);
public abstract long getLong( );
public abstract long getLong (int index);
public abstract ByteBuffer putLong (long value);
public abstract ByteBuffer putLong (int index, long value);
public abstract float getFloat( );
public abstract float getFloat (int index);
public abstract ByteBuffer putFloat (float value);
public abstract ByteBuffer putFloat (int index, float value);
public abstract double getDouble( );
public abstract double getDouble (int index);
public abstract ByteBuffer putDouble (double value);
public abstract ByteBuffer putDouble (int index, double value);
public abstract ByteBuffer compact( );
public boolean equals (Object ob) {
public int compareTo (Object ob) {
public String toString( )
public int hashCode( )
}
每个基本数据类型都是以连续字节序列的形式存储在内中。尽管字节大小已经确定,但字节顺序问题一直没有被广泛认同。
多字节数值被存储在内存中的方式一般被称为endian-ness。如果数字数值的最高字节(big end),位于低位地址,那么系统就是大端字节顺序。行转换。
package java.nio;
public final class ByteOrder
{
public static final ByteOrder BIG_ENDIAN
public static final ByteOrder LITTLE_ENDIAN
public static ByteOrder nativeOrder( )
public String toString( )
}
ByteOrder类定义了决定从缓冲区中存储或检索多个字节数值时使用哪一字节顺序的常量。
public abstract class ByteBuffer extends Buffer
implements Comparable
{
// This is a partial API listing
public final ByteOrder order( )
public final ByteBuffer order (ByteOrder bo)
}
视图的字节顺序设定在创建后不能被改变,而且如果原始的字节缓冲区的字节顺序在之后被改变,它也不会受到影响
字节缓冲区与其他缓冲区最明显的不同在于,它可以成为通道所执行的IO的源或目标。操作系统在内存区域中进行IO操作,在内存区域,就操作
系统而言,就是相连的字节序列。于是,只有字节缓冲区有资格参与IO操作。在JVM中,字节数组可能不会在内存中连续存储,或者无用存储单元收集
可能随时对其进行移动。出于这一原因,引入直接缓冲区,用来与通道和固有IO例程交互。
非直接字节缓冲区可以被传递给通道,这样做会导致性能损耗。如果向一个通道中传递一个非直接ByteBuffer对象用于写入,通道可能会在每次
调用中隐含进行一下操作:
1 创建临时的直接ByteBuffer对象
2 将非直接缓冲区的内容复制到临时缓冲区
3 使用临时缓冲区执行低层次IO操作。
4 临时缓冲区对象离开作用域,并最终成为被回收的无用数据。
这可能导致缓冲区在每个IO上复制并产生大量对象。直接缓冲区是IO的最佳选择,但比创建非直接缓冲区成本更高。直接缓冲区使用的内存是通
过调用本地操作系统的代码分配的,绕过了JVM堆栈。
直接 ByteBuffer 是通过调用具有所需容量的 ByteBuffer.allocateDirect()方法产生的。
public abstract class ByteBuffer
extends Buffer implements Comparable
{
// This is a partial API listing
public static ByteBuffer allocate (int capacity)
public static ByteBuffer allocateDirect (int capacity)
public abstract boolean isDirect( );
}
ByteBuffer 是唯一可以被直接分配的类型,但如果基础缓冲区是一个直接 ByteBuffer,对于非字节视图缓冲区,isDirect()可以是 true
视图缓冲区通过已存在的缓冲区对象实例的工厂方法来创建,它维护自己的属性、容量、位置、上界和标记,但与原来的缓冲区共享数据元素。
ByteBuffer提供了多个工厂方法来创建其他类型视图缓冲区,这些缓冲区是基础缓冲区的一个切分,由基础缓冲区的位置和上界决定。新的缓冲区的容量是字节缓冲区中存在的元素量除以视图类型中组成一个数据类型的字节数。
无论何时一个视图缓冲区存取一个 ByteBuffer 的基础字节,这些字节都会根据这个视图缓冲区的字节顺序设定被包装成一个数据元素。当一个视图缓冲区被创建时,视图创建的同时它也继承了基础 ByteBuffer 对象的字节顺序设定。
public abstract class ByteBuffer
extends Buffer implements Comparable
{
// This is a partial API listing
public abstract CharBuffer asCharBuffer( );
public abstract ShortBuffer asShortBuffer( );
public abstract IntBuffer asIntBuffer( );
public abstract LongBuffer asLongBuffer( );
public abstract FloatBuffer asFloatBuffer( );
public abstract DoubleBuffer asDoubleBuffer( );
}
public abstract class ByteBuffer
extends Buffer implements Comparable
{
public abstract char getChar( );
public abstract char getChar (int index);
public abstract short getShort( );
public abstract short getShort (int index);
public abstract int getInt( );
public abstract int getInt (int index);
public abstract long getLong( );
public abstract long getLong (int index);
public abstract float getFloat( );
public abstract float getFloat (int index);
public abstract double getDouble( );
public abstract double getDouble (int index);
public abstract ByteBuffer putChar (char value);
public abstract ByteBuffer putChar (int index, char value);
public abstract ByteBuffer putShort (short value);
public abstract ByteBuffer putShort (int index, short value);
public abstract ByteBuffer putInt (int value);
public abstract ByteBuffer putInt (int index, int value);
public abstract ByteBuffer putLong (long value);
public abstract ByteBuffer putLong (int index, long value);
public abstract ByteBuffer putFloat (float value);
public abstract ByteBuffer putFloat (int index, float value);
public abstract ByteBuffer putDouble (double value);
public abstract ByteBuffer putDouble (int index, double value);
}
这些方法从当前位置开始存取 ByteBuffer 的字节数据,就好像一个数据元素被存储在那里一样,据这个缓冲区的当前的有效的字节顺序,这些
public static short getUnsignedByte (ByteBuffer bb)
{
return ((short)(bb.get( ) & 0xff));
}