`

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

    博客分类:
  • Java
阅读更多

视图缓冲器(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());
		}
	}
}
分享到:
评论

相关推荐

    Android中的ByteBuffer解析

    2. **直接缓冲区**:对于性能敏感的应用,可以使用`ByteBuffer.allocateDirect(int capacity)`创建直接缓冲区,它直接在物理内存中分配空间,减少了Java对象头的开销,但可能涉及内存复制。 三、ByteBuffer的主要...

    Java NIO学习笔记——ByteBuffer用法

    本文主要关注的是Java NIO中的ByteBuffer,一个关键的数据容器,用于在通道(Channel)和缓冲区(Buffer)之间传输数据。ByteBuffer的用法是Java NIO学习中的核心内容。 首先,我们了解下ByteBuffer的基本概念。...

    Java中的缓冲区(直接缓冲区、非直接缓冲区等).docx

    ### Java中的缓冲区详解 #### 一、缓冲区概述 ...通过合理地使用直接缓冲区和非直接缓冲区,开发者可以显著提高应用程序的性能。了解缓冲区的基本概念、特性和使用方法对于任何Java开发者来说都是非常重要的。

    buffer:用于在PHP中操作二进制数据的简单库

    PHPinnacle缓冲区 PHPinnacle Buffer是用于在PHP中操作二进制数据的简单工具。 通常,它只是包装PHP打包/解包功能。安装通过作曲家$ composer require phpinnacle/buffer基本用法 &lt;?phpuse PHPinnacle \ Buffer \...

    java8中NIO缓冲区(Buffer)的数据存储详解

    Java8 中的 NIO 缓冲区(Buffer)提供了多种类型的缓冲区,包括 ByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer 等,每种类型的缓冲区都有其特定的用途和使用方法。...

    DataBuffer在Java中使用ADO.NET

    4. 读取和写入DataBuffer:现在你可以使用Recordset的GetBuffer和PutBuffer方法来获取和设置数据缓冲区。在Java中,我们可以创建一个ByteBuffer对象,然后通过JNA的指针操作将其与ADO.NET的DataBuffer关联。 ```...

    使用Buffer进行II/O操作

    Java中的Buffer类主要有ByteBuffer、CharBuffer、IntBuffer等,它们都是抽象类Buffer的子类,用于不同数据类型的缓冲操作。每个Buffer类都有特定的方法用于添加数据(put)、获取数据(get)以及检查数据位置...

    ByteBuffer.zip

    - 写入数据:使用ByteBuffer的put方法将转换后的字节序列写入缓冲区,可以按单个字节、短整型、整型、长整型或其他自定义字节数组进行写入。 - 对齐处理:如果需要,可以进行字节对齐,确保数据按照特定的边界对齐...

    深入理解Apache Mina (6)---- Java Nio ByteBuffer与Mina ByteBuffer的区别

    Java NIO的ByteBuffer是Java标准库提供的一个核心类,它是通道(Channel)和缓冲区(Buffer)之间数据传输的主要媒介。它允许我们直接在内存中操作数据,而无需频繁地进行磁盘或网络I/O操作,提高了程序性能。ByteBuffer...

    【IT十八掌徐培成】Java基础第26天-05.ByteBuffer-mark-pos-limit-cap-flip.zip

    首先,`ByteBuffer`是`Buffer`接口的一个实现,它是用来存储字节数据的缓冲区。`Buffer`家族还包括`CharBuffer`、`IntBuffer`等,分别对应不同的数据类型。 1. **Capacity**:容量是`Buffer`可以存储的最大数据量,...

    protobuf+long+bytebuffer

    本主题主要关注的是如何在JavaScript环境中结合protobuf.js库处理`long`类型的数据以及与`ByteBuffer`的配合使用。`long`类型在protobuf中用于表示大整数,而`ByteBuffer`则是protobuf.js提供的一种高效的数据缓冲区...

    Android在JNI中使用ByteBuffer的方法

    本文实例讲述了Android在JNI中使用ByteBuffer的方法。分享给大家供大家参考。具体如下: 一、ByteBuffer 定义 在NIO中,数据的读写操作始终是与缓冲区相关联的(读取时信道(SocketChannel)将数据读入缓冲区,写入时...

    缓冲池 java

    在Java编程中,缓冲池(Buffer Pool)是一个重要的概念,特别是在处理I/O操作时。缓冲池是一种内存管理技术,用于优化数据访问效率,减少磁盘I/O操作,并提高整体系统性能。它通过预先分配和复用内存块来实现这一...

    byte-buffer:JavaScript的ArrayBufferDataView的包装器可简化读写操作

    字节缓冲区 JavaScript的ArrayBuffer / DataView的包装器,用于维护索引和默认字节序。 支持任意读取/写入,隐式增长,剪切,克隆和反转以及UTF-8字符和以NULL结尾的C字符串。 安装 ByteBuffer可通过: npm install...

    学习笔记 java\CoreJava笔记\CoreJava_day21

    - **直接缓冲区**:在本机内存中分配空间,不受垃圾回收器管理,通常比非直接缓冲区更高效,但需谨慎使用。可通过`ByteBuffer.allocateDirect(int capacity)`创建。 ##### 2. 示例代码 ```java // 创建非直接缓冲区...

    pvDataNativeJava:使用 POJO 实现 pvData 序列化

    pvDataNativeJava 该项目使用 POJO 实现 pvData 序列化,而不是 pvData PV 容器类。 pvData 自省接口类和机制,其中使用 Java 反射 API 替换。... 序列化到缓冲区ByteBuffer buffer = ByteBuffer .

    java NIO原理和使用

    2. **缓冲区支持**:NIO 使用缓冲区来进行数据的读写操作,这提高了 I/O 操作的性能。 3. **散列和聚合**:NIO 提供了对多缓冲区读写的优化,比如可以通过单个操作将多个缓冲区的数据写入通道或从通道读取到多个缓冲...

    java new IO

    视图缓冲器(View Buffer)是NIO的另一项创新,它允许我们通过特定基础数据类型的视图来访问底层的ByteBuffer,如CharBuffer、ShortBuffer等。这种视图机制使得在ByteBuffer中操作不同数据类型变得更加便捷,而对...

Global site tag (gtag.js) - Google Analytics