使用缓冲视图(view buffer)操纵ByteBuffer

本文介绍了如何使用视图缓冲器(viewbuffers)来读写ByteBuffer中的数据。通过不同类型的视图缓冲器,如CharBuffer、ShortBuffer等,可以方便地处理各种基本数据类型,并展示了具体的Java代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

视图缓冲器(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里读写基本类型数据

 

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();
	}
}
 
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());
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值