本文共 8341 字,大约阅读时间需要 27 分钟。
视图缓冲器(view buffer)能让我们过某个特定的基本数据类型的视图查看其底层的ByteBuffer。换言之,就是把ByteBuffer里面的数据都看作某种primitive基本类型数据。但是视图view背后真正存储数据的地方是ByteBuffer,所以对view的任何操作都会作用到ByteBuffer上。正如下面这些实例,有了view,你就能很方便地把基本类型数据primitive读出/写入ByteBuffer了。另外view还能让你既可以一个一个地读/写(实质上就是ByteBuffer的方法)基本类型数据,也可以以批处理的方式(读进/写入一个数组)操作基本类型数据,当然你也可以直接使用ByteBuffer的相应基本类型数据的getXX方法来读基本类型数据。我们很方便地在同一个ByteBufferh建立不同的视图缓冲器,然后将同一字节序列翻译成short,int,float,long和double类型数据,请看ViewBuffers示例。
注,我们只能创建byte基本类型的这种缓冲器ByteBuffer,其余基本类型的缓冲器只能使用"as" 方法来获取。另外你不能把其它基本类型buffer转换成ByteBuffer,不过你可以用view buffer往ByteBuffer里读写基本类型数据。
Java代码 收藏代码 import java.nio.ByteBuffer; /* * 通过ByteBuffer的缓冲视图读写ByteBuffer字节缓冲 * */ public class ByteBufferGetData { public static void main(String[] args) { ByteBuffer bb = ByteBuffer.allocate(1024); //新创建的ByteBuffer时清零 int i = 0; //循环每个字节,看是否有不是零的 while (i++ < bb.limit()) { if (bb.get() != 0) { System.out.println("nonzero"); } } System.out.println("i = " + i);//1025 bb.rewind();//重置 /* * byteBuffer.asCharBuffer():获取CharBuffer缓冲视图,可用来直接写入字符 */ bb.asCharBuffer().put("你好!");//以UTF-16BE编码方式存储 char c; /* * byteBuffer.getChar():读取此缓冲区的当前位置之后的两个字节,根据当前的字节顺 * 序将它们组成 char 值,然后将该位置增加 2,默认编码为UTF-16BE */ while ((c = bb.getChar()) != 0) { System.out.print(c + " ");//你 好 ! } System.out.println(); bb.rewind();//重置 /* * byteBuffer.asShortBuffer():获取ShortBuffer缓冲视图,可用来直接写入short */ bb.asShortBuffer().put((short) 32767); /* * byteBuffer.getShort():读取此缓冲区的当前位置之后的两个字节,根据当前的字节顺 * 序将它们组成 short 值,然后将该位置增加 2。 */ System.out.println(bb.getShort());//32767 bb.rewind(); /* * byteBuffer.asIntBuffer():获取IntBuffer缓冲视图,可用来直接写入int */ bb.asIntBuffer().put(2147483647); /* * byteBuffer.getInt():读取此缓冲区的当前位置之后的 4 个字节,根据当前的 * 字节顺序将它们组成 int 值,然后将该位置增加 4。 */ System.out.println(bb.getInt());//2147483647 bb.rewind(); /* * byteBuffer.asLongBuffer():获取LongBuffer缓冲视图,可用来直接写入long */ bb.asLongBuffer().put(99471142); /* * byteBuffer.getLong():读取此缓冲区的当前位置之后的 8 个字节,根据当前的字节 * 顺序将它们组成 long 值,然后将该位置增加 8。 */ System.out.println(bb.getLong());//99471142 bb.rewind(); /* * byteBuffer.asFloatBuffer():获取FloatBuffer缓冲视图,可用来直接写入float */ bb.asFloatBuffer().put(99471142); /* * byteBuffer.getFloat():读取此缓冲区的当前位置之后的 4 个字节,根据当前的字节 * 顺序将它们组成 float 值,然后将该位置增加 4。 */ System.out.println(bb.getFloat());//9.9471144E7 bb.rewind(); /* * byteBuffer.asDoubleBuffer():获取DoubleBuffer缓冲视图,可用来直接写入double */ bb.asDoubleBuffer().put(99471142); /* * byteBuffer.getDouble():读取此缓冲区的当前位置之后的 8 个字节,根据当前的字节顺 * 序将它们组成 double 值,然后将该位置增加 8。 */ System.out.println(bb.getDouble());//9.9471142E7 bb.rewind(); } }
Java代码 收藏代码 import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.DoubleBuffer; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.nio.LongBuffer; import java.nio.ShortBuffer; /* * 使用Buffer视图操作java.nio.ByteBuffer * * +-------------------------------+ * | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 97| byte * +-------------------------------+ * | | | | a | char * +-------------------------------+ * | 0 | 0 | 0 | 97 | short * +-------------------------------+ * | 0 | 97 | int * +-------------------------------+ * | 0.0 | 1.36E-43 | float * +-------------------------------+ * | 97 | long * +-------------------------------+ * | 4.8E-322 | double * +-------------------------------+ */ public class ViewBuffers { public static void main(String[] args) { /* * 构造ByteBuffer缓冲,占用8个字节,最后一字节内容为实质上是97,整个 * 缓冲区连接起来就是64位 00000000.x.x.x.x.x.x.01100001 * * 运行结果: * Byte Buffer * 0 -> 0 * 1 -> 0 * 2 -> 0 * 3 -> 0 * 4 -> 0 * 5 -> 0 * 6 -> 0 * 7 -> 97 */ ByteBuffer bb = ByteBuffer.wrap(new byte[] { 0, 0, 0, 0, 0, 0, 0, 'a' }); bb.rewind(); System.out.println("Byte Buffer"); while (bb.hasRemaining()) { System.out.println(bb.position() + " -> " + bb.get()); } /* * 使用CharBuffer视图读取基本类型char字符数据,position两个字节两个字节往后移, * 最后得到4个char * * 运行结果: * Char Buffer * 0 -> * 1 -> * 2 -> * 3 -> */ CharBuffer cb = ((ByteBuffer) bb.rewind()).asCharBuffer(); System.out.println("Char Buffer"); while (cb.hasRemaining()) { System.out.println(cb.position() + " -> " + cb.get()); } /* * 使用FloatBuffer视图读取基本类型float字符数据,position4个字节4个字节往后移, * 最后得到2个float * * 运行结果: * Float Buffer * 0 -> 0.0 * 1 -> 1.36E-43 */ FloatBuffer fb = ((ByteBuffer) bb.rewind()).asFloatBuffer(); System.out.println("Float Buffer"); while (fb.hasRemaining()) { System.out.println(fb.position() + " -> " + fb.get()); } /* * 使用IntBuffer视图读取基本类型int字符数据,position4个字节4个字节往后移, * 最后得到2个int * * 运行结果: * Int Buffer * 0 -> 0 * 1 -> 97 */ IntBuffer ib = ((ByteBuffer) bb.rewind()).asIntBuffer(); System.out.println("Int Buffer"); while (ib.hasRemaining()) { System.out.println(ib.position() + " -> " + ib.get()); } /* * 使用LongBuffer视图读取基本类型long字符数据,position8个字节8个字节往后移, * 最后得到1个long * * 运行结果: * Long Buffer * 0 -> 97 */ LongBuffer lb = ((ByteBuffer) bb.rewind()).asLongBuffer(); System.out.println("Long Buffer"); while (lb.hasRemaining()) { System.out.println(lb.position() + " -> " + lb.get()); } /* * 使用ShortBuffer视图读取基本类型short字符数据,position2个字节2个字节往后移, * 最后得到4个short * * 运行结果: * 0 -> 0 * 1 -> 0 * 2 -> 0 * 3 -> 97 */ ShortBuffer sb = ((ByteBuffer) bb.rewind()).asShortBuffer(); System.out.println("Short Buffer"); while (sb.hasRemaining()) { System.out.println(sb.position() + " -> " + sb.get()); } /* * 使用DoubleBuffer视图读取基本类型double字符数据,position4个字节4个字节往后移, * 最后得到1个double * * Double Buffer * 0 -> 4.8E-322 */ DoubleBuffer db = ((ByteBuffer) bb.rewind()).asDoubleBuffer(); System.out.println("Double Buffer"); while (db.hasRemaining()) { System.out.println(db.position() + " -> " + db.get()); } } }
本文转自:http://jiangzhengjun.iteye.com/blog/514967 转载地址:http://rvopi.baihongyu.com/