Java Nio Buffer 五

2018/01/06 Java

Java Nio Buffer 五

数据元素视图

ByteBuffer 类提供了一个不太重要的机制来以多字节数据类型的形式存取 byte 数据。ByteBuffer 类为每一种原始数据类型提供了存取的和转化的方法:

 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 的字节数据,就好像一个数据元素被存储在那里一样。根据这个缓冲区的当前的有效的字节顺序,这些字节数据会被排列或打乱成需要的原始数据类型。如果 getInt()函数被调用,从当前的位置开始的四个字节会被包装成一个int 类型的变量然后作为函数的返回值返回。
这些函数返回的元素不需要被任何特定模块界限所限制。数值将会从以缓冲区的当前位置开始的字节缓冲区中取出并组合,无论内存是否对齐。
这样的做法是低效的,但是它允许对一个字节流中的数据进行随机的放置。对于从二进制文件数据或者包装数据成特定平台的格式或者导出到外部的系统,这是非常有用的。

如图所示: 图一

存取无符号数据

Java 编程语言对无符号数值并没有提供直接的支持(除了 char 类型)。但是在许多情况下需要将无符号的信息转化成数据流或者文件,或者包装数据来创建文件头或者其它带有无符号数据区域结构化的信息。ByteBuffer 类的 API 对此并没有提供直接的支持,实现不困难但是需要小心精度的问题。下面提供的工具类会有所帮助。

public class Unsigned{
    public static short getUnsignedByte (ByteBuffer bb){
        return ((short)(bb.get( ) & 0xff));
    }

    public static void putUnsignedByte (ByteBuffer bb, int value){
        bb.put ((byte)(value & 0xff));
    }

   public static short getUnsignedByte (ByteBuffer bb, int position){
        return ((short)(bb.get (position) & (short)0xff));
    }

   public static void putUnsignedByte (ByteBuffer bb, int position,
int value) {
        bb.put (position, (byte)(value & 0xff));
   }
   
   public static int getUnsignedShort (ByteBuffer bb){
        return (bb.getShort( ) & 0xffff);
    }

   public static void putUnsignedShort (ByteBuffer bb, int value){
        bb.putShort ((short)(value & 0xffff));
    }
   public static int getUnsignedShort (ByteBuffer bb, int position){
        return (bb.getShort (position) & 0xffff);
    }

   public static void putUnsignedShort (ByteBuffer bb, int position,
int value) {
        bb.putShort (position, (short)(value & 0xffff));
    }
   
   public static long getUnsignedInt (ByteBuffer bb){
        return ((long)bb.getInt( ) & 0xffffffffL); 
    }

    public static void putUnsignedInt (ByteBuffer bb, long value){
        bb.putInt ((int)(value & 0xffffffffL));
    }

    public static long getUnsignedInt (ByteBuffer bb, int position){
        return ((long)bb.getInt (position) & 0xffffffffL);
    }

    public static void putUnsignedInt (ByteBuffer bb, int position,
long value){
        bb.putInt (position, (int)(value & 0xffffffffL));
    }

}

内存映射缓冲区

映射缓冲区是带有存储在文件,通过内存映射来存取数据元素的字节缓冲区。映射缓冲区通常是直接存取内存的,只能通过 FileChannel 类创建。映射缓冲区的用法和直接缓冲区类似,但是 MappedByteBuffer 对象可以处理独立于文件存取形式的的许多特定字符。

Show Disqus Comments

Search

    Table of Contents