`

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

相关推荐

    java new IO

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

    dena-bytebuffer:dena-bytebuffer

    本文将详细探讨`dena-bytebuffer`的核心特性、使用方法以及其在实际项目中的应用。 一、`dena-bytebuffer`简介 `dena-bytebuffer`是基于JavaScript的字节缓冲库,它允许开发者以高效的方式处理二进制数据。在...

    Android开发问题集锦第一期[归纳].pdf

    `setPadding`设置的是视图内部的边距,影响视图内容区域的大小,而`setMargins`设置的是视图与其父视图之间的外边距,影响视图在布局中的位置。 问题八:Android最简单播放GIF动画方法 Android原生不支持GIF动图,...

    java学习路线.docx

    学习如何使用ByteBuffer、CharBuffer等不同类型的缓冲区。 - **通道(Channel):** 通道提供了与源节点和目标节点之间的连接。学习如何使用FileChannel、SocketChannel等。 - **选择器(Selector):** 选择器允许...

    STM32+OLED_净水器水流量计源码.rar

    STM32+OLED_净水器水流量计源码.rar

    【机会约束】机会约束优化研究 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    ,,基于EKF的三相PMSM无传感器矢量控制,基于卡尔曼滤波器的无速度传感器 ,核心关键词:基于EKF的三相PMSM无传感器矢量控制; 基于卡尔曼滤波器的无速度传感器 ,基于EKF与卡尔曼滤波器的三相

    ,,基于EKF的三相PMSM无传感器矢量控制,基于卡尔曼滤波器的无速度传感器 ,核心关键词:基于EKF的三相PMSM无传感器矢量控制; 基于卡尔曼滤波器的无速度传感器。,基于EKF与卡尔曼滤波器的三相PMSM无传感器矢量控制研究

    56页-智慧双碳园区建设方案.pdf

    在智慧城市建设的大潮中,智慧园区作为其中的璀璨明珠,正以其独特的魅力引领着产业园区的新一轮变革。想象一下,一个集绿色、高端、智能、创新于一体的未来园区,它不仅融合了科技研发、商业居住、办公文创等多种功能,更通过深度应用信息技术,实现了从传统到智慧的华丽转身。 智慧园区通过“四化”建设——即园区运营精细化、园区体验智能化、园区服务专业化和园区设施信息化,彻底颠覆了传统园区的管理模式。在这里,基础设施的数据收集与分析让管理变得更加主动和高效,从温湿度监控到烟雾报警,从消防水箱液位监测到消防栓防盗水装置,每一处细节都彰显着智能的力量。而远程抄表、空调和变配电的智能化管控,更是在节能降耗的同时,极大地提升了园区的运维效率。更令人兴奋的是,通过智慧监控、人流统计和自动访客系统等高科技手段,园区的安全防范能力得到了质的飞跃,让每一位入驻企业和个人都能享受到“拎包入住”般的便捷与安心。 更令人瞩目的是,智慧园区还构建了集信息服务、企业服务、物业服务于一体的综合服务体系。无论是通过园区门户进行信息查询、投诉反馈,还是享受便捷的电商服务、法律咨询和融资支持,亦或是利用云ERP和云OA系统提升企业的管理水平和运营效率,智慧园区都以其全面、专业、高效的服务,为企业的发展插上了腾飞的翅膀。而这一切的背后,是大数据、云计算、人工智能等前沿技术的深度融合与应用,它们如同智慧的大脑,让园区的管理和服务变得更加聪明、更加贴心。走进智慧园区,就像踏入了一个充满无限可能的未来世界,这里不仅有科技的魅力,更有生活的温度,让人不禁对未来充满了无限的憧憬与期待。

    BST的S变换的批处理研究 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    书房中如何利用镜面增加空间感与光线.doc

    书房中如何利用镜面增加空间感与光线

    电动汽车充电站的最优选址和定容【两种方法】 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    ,,pmsm电阻电感磁链常数辨识源码 电阻,电感,磁链常数辨识 程序在ti dsp实现 在ti开源foc框架基础上开发 能够辨识电机电阻,电感,磁链常数 精度较高,能够满足foc控制需要

    ,,pmsm电阻电感磁链常数辨识源码 电阻,电感,磁链常数辨识。 程序在ti dsp实现。 在ti开源foc框架基础上开发。 能够辨识电机电阻,电感,磁链常数。 精度较高,能够满足foc控制需要。 辨识时间短,大约两秒完成电阻电感辨识。 磁链辨识需要电机旋转。 多次辨识,结果一致性好。 辨识部分代码不包含寄存器操作,易于跨平台移植。 辨识大致原理: 电阻辨识发一个固定的电压矢量,检测电流 电感辨识发一个高频旋转的电压矢量,检测电流,计算感抗。 磁链辨识通过if控制让电机旋转,通过电压电流模型计算转子磁链分量。 ,PMSM; 电阻电感磁链常数辨识; TI DSP实现; TI开源FOC框架; 电机参数辨识; 高精度; 短辨识时间; 跨平台移植; 电阻辨识原理; 电感辨识原理; 磁链辨识原理。,基于TI DSP的PMSM电阻电感磁链常数快速高精度辨识源码

    ,,三菱,FX3U,plc程序模板和触摸屏程序模板,适用于运动轴控制,程序可以在自动的时候暂停进行手动控制,适用于一些中大型设备,可以防止某个气缸超时时,处于自动模式,能够轻松处理,处理完成后,恢复原

    ,,三菱,FX3U,plc程序模板和触摸屏程序模板,适用于运动轴控制,程序可以在自动的时候暂停进行手动控制,适用于一些中大型设备,可以防止某个气缸超时时,处于自动模式,能够轻松处理,处理完成后,恢复原来的气缸,解除暂停即可,思路清晰,编程效率大大提高,程序里附带和仪表的无协议通讯,并且附带最常用的手册。 ,关键词:三菱;FX3U;PLC程序模板;触摸屏程序模板;运动轴控制;自动/手动控制;气缸超时处理;无协议通讯;编程效率;最常用手册。,三菱FX3U PLC程序模板:中大型设备运动轴控制与气缸超时保护

    Matlab实现基于BO贝叶斯优化Transformer结合GRU门控循环单元时间序列预测的详细项目实例(含完整的程序,GUI设计和代码详解)

    内容概要:本文介绍了使用 Matlab 实现基于 BO(贝叶斯优化)的 Transformer 结合 GRU 门控循环单元时间序列预测的具体项目案例。文章首先介绍了时间序列预测的重要性及其现有方法存在的限制,随后深入阐述了该项目的目标、挑战与特色。重点描述了项目中采用的技术手段——结合 Transformer 和 GRU 模型的优点,通过贝叶斯优化进行超参数调整。文中给出了模型的具体实现步骤、代码示例以及完整的项目流程。同时强调了数据预处理、特征提取、窗口化分割、超参数搜索等关键技术点,并讨论了系统的设计部署细节、可视化界面制作等内容。 适合人群:具有一定机器学习基础,尤其是熟悉时间序列预测与深度学习的科研工作者或从业者。 使用场景及目标:适用于金融、医疗、能源等多个行业的高精度时间序列预测。该模型可通过捕捉长时间跨度下的复杂模式,提供更为精准的趋势预判,辅助相关机构作出合理的前瞻规划。 其他说明:此项目还涵盖了从数据采集到模型发布的全流程讲解,以及GUI图形用户界面的设计实现,有助于用户友好性提升和技术应用落地。此外,文档包含了详尽的操作指南和丰富的附录资料,包括完整的程序清单、性能评价指标等,便于读者动手实践。

    分布式光伏储能系统的优化配置方法 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    UQP 启发式方法研究 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    自驾游中的导航技巧提升.doc

    自驾游中的导航技巧提升

    各个操作系统版本的gdal2.4库(包括win32、win64、centos7、centosAarch64、c#、linux32、ubuntu64)

    各个操作系统版本的gdal2.4库(包括win32、win64、centos7、centosAarch64、c#、linux32、ubuntu64)。 GDAL(Geospatial Data Abstraction Library)是一个在X/MIT许可协议下的开源栅格空间数据转换库。以下是对GDAL库的详细介绍: 全称:Geospatial Data Abstraction Library 性质:开源栅格空间数据转换库 用途:进行数据转换和处理 开发语言:C/C++ 数据格式支持:GDAL支持大量的栅格和矢量数据格式,包括常见的地理空间数据格式如GeoTIFF、ESRI Shapefile、GeoJSON、NetCDF、GML等,以及一些专用格式。 数据读取和写入:GDAL可以从不同的数据源中读取地理空间数据,例如文件、数据库、网络服务等,并且可以将数据写入到不同的输出格式。 数据转换和处理:GDAL可以进行各种数据转换和处理操作,包括坐标系转换、重采样、镶嵌、裁剪、投影变换等。此外,它还提供了图像处理和分析功能,如颜色空间转换、直方图均衡化、图像融合、图像代数等。

    漫画作品与人工智能想象.doc

    漫画作品与人工智能想象

Global site tag (gtag.js) - Google Analytics