在GetChannel.java程序中,为了输出文件中的信息,我们每次只读取一个字节的数据,然后将每个byte类型强制转换成char类型。这种方法看起来有点原始,如果我们查看java.nio.CharBuffer这个类,将会发现它有一个toString()方法的定义为:Returns a string containing the characters in this buffer(返回一个包含缓冲区所有字符的字符串)。ByteBuffer是具有asCharBuffer()方法返回一个CharBuffer。那么我们就可以使用此方式输出字符串,但是,从输出的第一行可以看出,这种方法不太恰当。
缓冲器容纳的是普通的字符,为了把它们转换成字符,我们要么在输入它们时对其进行编码,要么在将其从缓冲器输出时对它们进行解码。如程序中所写,使用java.nio.charset.Charset便可以实现这些功能。
我们看最后一个部分,我们通过CharBuffer向ByteBuffer中写入。为ByteBuffer分配了12字节。一个字符需要两个字符,ByteBuffer可以容纳6个字符,我们的"Some"占4个字符,可是我们看输出结果,发现剩下的两个没有内容的字符也会被输出。
获取基本数据类型尽管ByteBuffer只能保存字节类型的数据,但是它具有可以从其所容纳的字节中产生出各种不同基本数据类型的方法。下面将展示如何使用这些方法来插入和读取各种数值。
public class GetData { private static final int BSIZE = 1024; public static void main(String[] args) { ByteBuffer bb = ByteBuffer.allocate(BSIZE); int i = 0; //检测缓冲器的初始内容是否为0 while(i ++ < bb.limit()) { if(bb.get() != 0) System.out.println("nozero"); } System.out.println("i = " + i); bb.rewind(); bb.asCharBuffer().put("Happpy!"); char c; while((c = bb.getChar()) != 0) { System.out.print(c+"\t"); } System.out.println(); bb.rewind(); bb.asShortBuffer().put((short)471142);//超过short类型最大值32767需要强制类型转换 会截断 System.out.println(bb.getShort()); bb.rewind(); bb.asIntBuffer().put(99471142); System.out.println(bb.getInt()); bb.rewind(); bb.asLongBuffer().put(99471142); System.out.println(bb.getLong()); bb.rewind(); bb.asFloatBuffer().put(99471142); System.out.println(bb.getFloat()); bb.rewind(); bb.asDoubleBuffer().put(99471142); System.out.println(bb.getDouble()); } } /* output: i = 1025 H a p p p y ! 12390 99471142 99471142 9.9471144E7 9.9471142E7 */向ByteBuffer插入基本类型数据的最简单的方法是:利用asCharBuffer()、asShortBuffer()等获得该缓冲器上的视图,然后使用该视图的put()方法。
视图缓冲器视图缓冲器(view buffer)可以让我们通过某个特定的基本数据类型的视窗查看其底层的ByteBuffer。ByteBuffer依旧是实际存储数据的地方,“支持”着视图,因此,对视图的任何修改都会映射为对ByteBuffer中数据的修改。如上面程序中所示,使用视图可以很方便地向ByteBuffer中插入数据与读取数据。
在同一个ByteBuffer上建立不同的视图缓冲器,将同一字节序列翻译成char、short、int、float、long和double类型的数据。
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(); //读取成字符 bb.rewind(); CharBuffer cb = bb.asCharBuffer(); System.out.print("Char Buffer: "); while(cb.hasRemaining()) { System.out.print(cb.position() + ":" + cb.get() + ", "); } System.out.println(); //读取短整型 bb.rewind(); ShortBuffer sb = bb.asShortBuffer(); System.out.print("Short Buffer: "); while(sb.hasRemaining()) { System.out.print(sb.position() + ":" + sb.get() + ", "); } System.out.println(); //读取成单精度浮点型 bb.rewind(); FloatBuffer fb = bb.asFloatBuffer(); System.out.print("Float Buffer: "); while(fb.hasRemaining()) { System.out.print(fb.position() + ":" + fb.get() + ", "); } System.out.println(); //读取整型 bb.rewind(); IntBuffer ib = bb.asIntBuffer(); System.out.print("Int Buffer: "); while(ib.hasRemaining()) { System.out.print(ib.position() + ":" + ib.get() + ", "); } System.out.println(); //读取长整型 bb.rewind(); LongBuffer lb = bb.asLongBuffer(); System.out.print("Long Buffer: "); while(lb.hasRemaining()) { System.out.print(lb.position() + ":" + lb.get() + ", "); } System.out.println(); //读取双精度浮点型 bb.rewind(); DoubleBuffer db = bb.asDoubleBuffer(); System.out.print("Double Buffer: "); while(db.hasRemaining()) { System.out.print(db.position() + ":" + db.get() + ", "); } } }