“视图缓冲器(view buffer)”可以让我们通过某个特定的基本数据类型的视窗查看其底层
的 ByteBuffer。ByteBuffer 依然是实际存储数据的地方,“支持”着前面的视图,因此,对
视图的任何修改都会映射成为对 ByteBuffer 中数据的修改。正如我们在上一示例看到的那
样,这使我们可以很方便地向 ByteBuffer 插入数据。视图还允许我们从 ByteBuffer 一次
一个地(与 ByteBuffer 所支持的相同)或者成批地(放入数组中)读取基本数据。在下面
这个例子中,通过 IntBuffer 操纵 ByteBuffer 中的整数:
//: c12:IntBufferDemo.java
// Manipulating ints in a ByteBuffer with an IntBuffer
import java.nio.*;
import com.bruceeckel.simpletest.*;
import com.bruceeckel.util.*;
public class IntBufferDemo {
private static Test monitor = new Test();
private static final int BSIZE = 1024;
public static void main(String[] args) {
ByteBuffer bb = ByteBuffer.allocate(BSIZE);
IntBuffer ib = bb.asIntBuffer();
// Store an array of int:
ib.put(new int[] { 11, 42, 47, 99, 143, 811, 1016 });
// Absolute location read and write:
System.out.println(ib.get(3));
ib.put(3, 1811);
ib.rewind();
while(ib.hasRemaining()) {
int i = ib.get();
if(i == 0) break; // Else we'll get the entire buffer
System.out.println(i);
}
monitor.expect(new String[] {
"99",
"11",
"42",
"47",
"1811",
"143",
"811",
"1016"
});
}
} ///:~
先用重载过的 put()方法存储一个整数数组。接着 get( )和 put( )的方法调用直接访问
底层的 ByteBuffer 中的某个整数位置。注意,这些对绝对位置的访问通过直接与
ByteBuffer 对话的方式也同样可以做用于基本类型。
一旦底层的 ByteBuffer 通过视图缓冲器被填满整数或其他基本类型时,就可以直接被写到
通道中了。正像从通道中读取那样容易,然后使用视图缓冲器可以把任何数据都转化成某一
特定的基本类型。在下面的例子中,通过在同一个 ByteBuffer 上建立不同的视图缓冲器,
将同一字节序列翻译成了 short, int, float, long, 和 double 类型的数据。
//: c12:ViewBuffers.java
import java.nio.*;
import com.bruceeckel.simpletest.*;
public class ViewBuffers {
private static Test monitor = new Test();
public static void main(String[] args) {
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 cb =
((ByteBuffer)bb.rewind()).asCharBuffer();
System.out.println("Char Buffer");
while(cb.hasRemaining())
System.out.println(cb.position()+ " -> " + cb.get());
FloatBuffer fb =
((ByteBuffer)bb.rewind()).asFloatBuffer();
System.out.println("Float Buffer");
while(fb.hasRemaining())
System.out.println(fb.position()+ " -> " + fb.get());
IntBuffer ib =
((ByteBuffer)bb.rewind()).asIntBuffer();
System.out.println("Int Buffer");
while(ib.hasRemaining())
System.out.println(ib.position()+ " -> " + ib.get());
LongBuffer lb =
((ByteBuffer)bb.rewind()).asLongBuffer();
System.out.println("Long Buffer");
while(lb.hasRemaining())
System.out.println(lb.position()+ " -> " + lb.get());
ShortBuffer sb =
((ByteBuffer)bb.rewind()).asShortBuffer();
System.out.println("Short Buffer");
while(sb.hasRemaining())
System.out.println(sb.position()+ " -> " + sb.get());
DoubleBuffer db =
((ByteBuffer)bb.rewind()).asDoubleBuffer();
System.out.println("Double Buffer");
while(db.hasRemaining())
System.out.println(db.position()+ " -> " + db.get());
monitor.expect(new String[] {
"Byte Buffer",
"0 -> 0",
"1 -> 0",
"2 -> 0",
"3 -> 0",
"4 -> 0",
"5 -> 0",
"6 -> 0",
"7 -> 97",
"Char Buffer",
"0 -> \0",
"1 -> \0",
"2 -> \0",
"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 字节数组,然后通过各种不同的基本类型的视图缓冲器
把它显示了出来。我们可以在下图中看到,当从不同类型的缓冲器读取时,数据显示的方式
的 ByteBuffer。ByteBuffer 依然是实际存储数据的地方,“支持”着前面的视图,因此,对
视图的任何修改都会映射成为对 ByteBuffer 中数据的修改。正如我们在上一示例看到的那
样,这使我们可以很方便地向 ByteBuffer 插入数据。视图还允许我们从 ByteBuffer 一次
一个地(与 ByteBuffer 所支持的相同)或者成批地(放入数组中)读取基本数据。在下面
这个例子中,通过 IntBuffer 操纵 ByteBuffer 中的整数:
//: c12:IntBufferDemo.java
// Manipulating ints in a ByteBuffer with an IntBuffer
import java.nio.*;
import com.bruceeckel.simpletest.*;
import com.bruceeckel.util.*;
public class IntBufferDemo {
private static Test monitor = new Test();
private static final int BSIZE = 1024;
public static void main(String[] args) {
ByteBuffer bb = ByteBuffer.allocate(BSIZE);
IntBuffer ib = bb.asIntBuffer();
// Store an array of int:
ib.put(new int[] { 11, 42, 47, 99, 143, 811, 1016 });
// Absolute location read and write:
System.out.println(ib.get(3));
ib.put(3, 1811);
ib.rewind();
while(ib.hasRemaining()) {
int i = ib.get();
if(i == 0) break; // Else we'll get the entire buffer
System.out.println(i);
}
monitor.expect(new String[] {
"99",
"11",
"42",
"47",
"1811",
"143",
"811",
"1016"
});
}
} ///:~
先用重载过的 put()方法存储一个整数数组。接着 get( )和 put( )的方法调用直接访问
底层的 ByteBuffer 中的某个整数位置。注意,这些对绝对位置的访问通过直接与
ByteBuffer 对话的方式也同样可以做用于基本类型。
一旦底层的 ByteBuffer 通过视图缓冲器被填满整数或其他基本类型时,就可以直接被写到
通道中了。正像从通道中读取那样容易,然后使用视图缓冲器可以把任何数据都转化成某一
特定的基本类型。在下面的例子中,通过在同一个 ByteBuffer 上建立不同的视图缓冲器,
将同一字节序列翻译成了 short, int, float, long, 和 double 类型的数据。
//: c12:ViewBuffers.java
import java.nio.*;
import com.bruceeckel.simpletest.*;
public class ViewBuffers {
private static Test monitor = new Test();
public static void main(String[] args) {
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 cb =
((ByteBuffer)bb.rewind()).asCharBuffer();
System.out.println("Char Buffer");
while(cb.hasRemaining())
System.out.println(cb.position()+ " -> " + cb.get());
FloatBuffer fb =
((ByteBuffer)bb.rewind()).asFloatBuffer();
System.out.println("Float Buffer");
while(fb.hasRemaining())
System.out.println(fb.position()+ " -> " + fb.get());
IntBuffer ib =
((ByteBuffer)bb.rewind()).asIntBuffer();
System.out.println("Int Buffer");
while(ib.hasRemaining())
System.out.println(ib.position()+ " -> " + ib.get());
LongBuffer lb =
((ByteBuffer)bb.rewind()).asLongBuffer();
System.out.println("Long Buffer");
while(lb.hasRemaining())
System.out.println(lb.position()+ " -> " + lb.get());
ShortBuffer sb =
((ByteBuffer)bb.rewind()).asShortBuffer();
System.out.println("Short Buffer");
while(sb.hasRemaining())
System.out.println(sb.position()+ " -> " + sb.get());
DoubleBuffer db =
((ByteBuffer)bb.rewind()).asDoubleBuffer();
System.out.println("Double Buffer");
while(db.hasRemaining())
System.out.println(db.position()+ " -> " + db.get());
monitor.expect(new String[] {
"Byte Buffer",
"0 -> 0",
"1 -> 0",
"2 -> 0",
"3 -> 0",
"4 -> 0",
"5 -> 0",
"6 -> 0",
"7 -> 97",
"Char Buffer",
"0 -> \0",
"1 -> \0",
"2 -> \0",
"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 字节数组,然后通过各种不同的基本类型的视图缓冲器
把它显示了出来。我们可以在下图中看到,当从不同类型的缓冲器读取时,数据显示的方式
也不同。