ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
<!-- View Buffers --> ## 视图缓冲区 “视图缓冲区”(view buffer)是通过特定的基本类型的窗口来查看底层 **ByteBuffer**。**ByteBuffer** 仍然是“支持”视图的实际存储,因此对视图所做的任何更改都反映在对 **ByteBuffer** 中的数据的修改中。 如前面的示例所示,这方便地将基本类型插入 **ByteBuffer**。视图缓冲区还可以从 **ByteBuffer** 读取基本类型数据,每次单个(**ByteBuffer** 规定),或者批量读取到数组。下面是一个通过 **IntBuffer** 在 **ByteBuffer** 中操作 **int** 的例子: ```java // newio/IntBufferDemo.java // (c)2017 MindView LLC: see Copyright.txt // 我们无法保证该代码是否适用于其他用途。 // 访问 http://OnJava8.com 了解更多本书信息。 // 利用 IntBuffer 保存 int 数据到 ByteBuffer import java.nio.*; public class IntBufferDemo { private static final int BSIZE = 1024; public static void main(String[] args) { ByteBuffer bb = ByteBuffer.allocate(BSIZE); IntBuffer ib = bb.asIntBuffer(); // 保存 int 数组: ib.put(new int[]{ 11, 42, 47, 99, 143, 811, 1016 }); //绝对位置读写: System.out.println(ib.get(3)); ib.put(3, 1811); // 在重置缓冲区前设置新的限制 ib.flip(); while(ib.hasRemaining()) { int i = ib.get(); System.out.println(i); } } } ``` 输出结果: ``` 99 11 42 47 1811 143 811 1016 ``` `put()` 方法重载,首先用于存储 **int** 数组。下面的 `get()` 和 `put()` 方法调用直接访问底层 **ByteBuffer** 中的 **int** 位置。**注意**,通过直接操作 **ByteBuffer** ,这些绝对位置访问也可以用于基本类型。 一旦底层 **ByteBuffer** 通过视图缓冲区填充了 **int** 或其他基本类型,那么就可以直接将该 **ByteBuffer** 写入通道。你可以轻松地从通道读取数据,并使用视图缓冲区将所有内容转换为特定的基本类型。下面是一个例子,通过在同一个 **ByteBuffer** 上生成不同的视图缓冲区,将相同的字节序列解释为 **short**、**int**、**float**、**long** 和 **double**。代码示例: ```java // newio/ViewBuffers.java // (c)2017 MindView LLC: see Copyright.txt // 我们无法保证该代码是否适用于其他用途。 // 访问 http://OnJava8.com 了解更多本书信息。 import java.nio.*; public class ViewBuffers { public static void main(String[] args) { ByteBuffer bb = ByteBuffer.wrap( new byte[]{ 0, 0, 0, 0, 0, 0, 0, 'a' }); bb.rewind(); System.out.print("Byte Buffer "); while(bb.hasRemaining()) System.out.print( bb.position()+ " -> " + bb.get() + ", "); System.out.println(); CharBuffer cb = ((ByteBuffer)bb.rewind()).asCharBuffer(); System.out.print("Char Buffer "); while(cb.hasRemaining()) System.out.print( cb.position() + " -> " + cb.get() + ", "); System.out.println(); FloatBuffer fb = ((ByteBuffer)bb.rewind()).asFloatBuffer(); System.out.print("Float Buffer "); while(fb.hasRemaining()) System.out.print( fb.position()+ " -> " + fb.get() + ", "); System.out.println(); IntBuffer ib = ((ByteBuffer)bb.rewind()).asIntBuffer(); System.out.print("Int Buffer "); while(ib.hasRemaining()) System.out.print( ib.position()+ " -> " + ib.get() + ", "); System.out.println(); LongBuffer lb = ((ByteBuffer)bb.rewind()).asLongBuffer(); System.out.print("Long Buffer "); while(lb.hasRemaining()) System.out.print( lb.position()+ " -> " + lb.get() + ", "); System.out.println(); ShortBuffer sb = ((ByteBuffer)bb.rewind()).asShortBuffer(); System.out.print("Short Buffer "); while(sb.hasRemaining()) System.out.print( sb.position()+ " -> " + sb.get() + ", "); System.out.println(); DoubleBuffer db = ((ByteBuffer)bb.rewind()).asDoubleBuffer(); System.out.print("Double Buffer "); while(db.hasRemaining()) System.out.print( db.position()+ " -> " + db.get() + ", "); } } ``` 输出结果: ``` Byte Buffer 0 -> 0, 1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0, 5 -> 0, 6 -> 0, 7 -> 97, Char Buffer 0 -> NUL, 1 -> NUL, 2 -> NUL, 3 -> a, Float Buffer 0 -> 0.0, 1 -> 1.36E-43, Int Buffer 0 -> 0, 1 -> 97, Long Buffer 0 -> 97, Short Buffer 0 -> 0, 1 -> 0, 2 -> 0, 3 -> 97, Double Buffer 0 -> 4.8E-322, ``` **ByteBuffer** 通过“包装”一个 8 字节数组生成,然后通过所有不同基本类型的视图缓冲区显示该数组。下图显示了从不同类型的缓冲区读取数据时,数据显示的差异: ![1554546258113](../images/1554546258113.png)