如何将 java.nio.ByteBuffer 转为 String

server/2024/9/23 17:29:41/

javanioByteBuffer__String_0">如何将 java.nio.ByteBuffer 转为 String

方法1: newString()方法结合ByteBuffer的array()方法, 忽略是否flip()过

用String的 public String(byte[] bytes, int offset, int length, Charset charset)方法 和 ByteBuffer的array()方法
长度在取 bbf.position()==0?bbf.limit():bbf.position() , 可无视是否flip()

new String(byteBuffer.array() , 0 , position==0?limit:position , StandardCharsets.UTF_8)

java">import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;public class TestByteBuffer2409180103 {public static boolean pln=true;public static void pln(Object...oAr) {if(pln)for(Object o:oAr)System.out.println(o);}public static void sleep(long l) {try {Thread.sleep(l);}catch(Exception e) {throw new RuntimeException(e);}}public static void main(String...arguments) {ByteBuffer bbf = ByteBuffer.allocate(102400);bbf.put("hello".getBytes());String str = new String(bbf.array(), 0, bbf.position()==0?bbf.limit():bbf.position(), StandardCharsets.UTF_8);bbf.flip();String str2 = new String(bbf.array(), 0, bbf.position()==0?bbf.limit():bbf.position(), StandardCharsets.UTF_8);pln(str, str2);}}

方法3: 用Charset的decode方法 , 必须有flip()

java">import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;public class ByteBufferToStringExample {public static void main(String[] args) {// 假设我们有一些字节数据(以UTF-8编码的字符串"Hello, World!")byte[] bytes = "Hello, World!".getBytes(StandardCharsets.UTF_8);// 将字节数据放入ByteBufferByteBuffer buffer = ByteBuffer.wrap(bytes);// 将ByteBuffer转换为String// 方法1: 使用StandardCharsets.UTF_8.decode()//  这里没调用 flip() 是因为ByteBuffer容量用满, 如果没满,结果就不正确String str1 = StandardCharsets.UTF_8.decode(buffer).toString();// 注意:上面的方法调用后,buffer的position会被移动到末尾,如果需要再次读取,需要调用buffer.position(0)// 方法2: 使用ByteBuffer的flip()和CharBuffer的toString()buffer.flip(); // 切换为读模式String str2 = Charset.forName("UTF-8").decode(buffer).toString();// 或者,如果你确定ByteBuffer中的字节确实代表了一个字符串,并且你知道字符集// 你可以直接使用ByteBuffer的array()和String的构造函数(但注意,这可能会抛出异常)// 注意:ByteBuffer.array()方法仅在ByteBuffer是通过wrap或allocateArray等方法创建时才有效// byte[] byteArray = buffer.array();// String str3 = new String(byteArray, StandardCharsets.UTF_8);// 输出结果System.out.println(str1); // 输出: Hello, World!System.out.println(str2); // 输出: Hello, World!// 如果使用了ByteBuffer.array(),取消注释上面的代码并注释掉其他输出以查看结果}
}

注意

  • 调用StandardCharsets.UTF_8.decode(buffer)前要调用buffer.flip()方法, 上面的例子没调用也结果正确是因为容量正好用满
  • StandardCharsets.UTF_8.decode(buffer)会读取缓冲区中的字节,直到遇到limit,然后将其解码为字符。调用此方法后,ByteBufferposition会被更新为limit,因此如果你需要再次从缓冲区读取数据,你需要重置position
  • 使用ByteBuffer.array()方法将ByteBuffer转换为字节数组然后构造String实例的方法,虽然简单,但有其局限性。首先,它要求ByteBuffer是基于数组的(即,它是由wrapallocateArray等方法创建的),而且它会返回整个底层数组,而不仅仅是缓冲区中有效的字节部分。如果你知道缓冲区中的字节确实代表了一个完整的字符串,并且你知道字符集,那么这种方法是可行的,但通常不推荐这样做,因为它违反了封装原则。
  • 在实际应用中,推荐使用CharsetDecoderStandardCharsets.UTF_8.decode(buffer)等方法来解码ByteBuffer,因为它们提供了更好的灵活性和安全性。

方法3: 用get(byte[] bar)方法将有效内容放入新数组, get前必须flip

java">        bbf.flip();  //必须有flip()byte[] bar22 = new byte[bbf.limit()]; bbf.get(bar22);String str22 = new String(bar22, StandardCharsets.UTF_8);

测试用例

测试1

java">import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;public class TestByteBuffer2409180152 {public static boolean pln=true;public static void pln(Object...oAr) {if(pln)for(Object o:oAr)System.out.println(o);}public static void sleep(long l) {try {Thread.sleep(l);}catch(Exception e) {throw new RuntimeException(e);}}public static void main(String...arguments) {ByteBuffer bbf = ByteBuffer.allocate(102400);bbf.put("hello".getBytes());String str = new String(bbf.array(), 0, bbf.position()==0?bbf.limit():bbf.position(), StandardCharsets.UTF_8);
//		bbf.flip();  //可有可无flip()String str2 = new String(bbf.array(), 0, bbf.position()==0?bbf.limit():bbf.position(), StandardCharsets.UTF_8);String str3 = new String(bbf.array(), 0, bbf.position()==0?bbf.limit():bbf.position(), StandardCharsets.UTF_8);bbf.flip();  //可有可无flip()String str4 = new String(bbf.array(), 0, bbf.position()==0?bbf.limit():bbf.position(), StandardCharsets.UTF_8);String str11 = StandardCharsets.UTF_8.decode(bbf).toString();bbf.flip();  //必须有flip()String str12 = Charset.forName("UTF-8").decode(bbf).toString();bbf.flip();  //必须有flip()String str13 = StandardCharsets.UTF_8.decode(bbf).toString();bbf.flip();  //必须有flip()String str14 = Charset.forName("UTF-8").decode(bbf).toString();//        bbf.flip();  //必须有flip()bbf.position(0);byte[] bar21 = new byte[bbf.limit()]; bbf.get(bar21);String str21 = new String(bar21, StandardCharsets.UTF_8);bbf.flip();  //必须有flip()byte[] bar22 = new byte[bbf.limit()]; bbf.get(bar22);String str22 = new String(bar22, StandardCharsets.UTF_8);pln(str, str2, str3, str4, str11, str12, str13, str14, str21, str22);}}

http://www.ppmy.cn/server/120891.html

相关文章

银河麒麟桌面操作系统V10(SP1)离线升级SSH(OpenSSH)服务

目录 前言 准备工作 准备与目标服务器相同版本的操作系统 准备编译依赖包 下载OpenSSL源码包 下载OpenSSH源码包 升级OpenSSH服务 查看当前版本信息 安装编译依赖包 安装OpenSSL 安装OpenSSH 前言 OpenSSH是一个广泛使用的开源SSH(安全壳)协议的实现,它提供了安…

Android对象池的深入理解和使用

参考文献:https://www.jianshu.com/p/eb04e4e1869d 判断对象是否可以被回收 垃圾收集算法 内存分配与回收策略

安卓13长按电源按键直接关机 andriod13不显示关机对话框直接关机

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改5.编译6.彩蛋1.前言 有些设备需要在长按电源键的时候,直接关机。不需要弹出对话框进行询问。 2.问题分析 过滤电源按键,需要在系统里面处理的话,那么我们需要熟悉android的事件分发,然后再…

ARM概念

一.CPU CPU:计算机的核心部件,负责执行指令和处理数据。它可以被视为计算机的“大脑”,负责运算、控制和数据传输等任务。 SoC(系统级芯片)是将多个组件集成在一个芯片上的设计,通常包括CPU、GPU、内存、…

关于less的基本使用

1、介绍及概述 1.1、解释 less 是方便开发人员书写CSS的一门预处理语言。浏览器只认识html /css /js格式的文件,所以直接引入.less文件,没有任何的效果,需要把less文件转换成css文件 1.2、概述 CSS弊端: 没有逻辑性、变量、函…

[数据集][目标检测]棉花叶子病害检测数据集VOC+YOLO格式977张22类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):977 标注数量(xml文件个数):977 标注数量(txt文件个数):977 标注类别…

语言的复合语句

复合语句有时被称为块语句,在编程语言世界占据重要的作用。最早Algol 60提出复合语句概念,直接影响了后面几乎所有编程语言。 为了支持一种条件下多条语句的执行,编程语言引入了”复合语句”。思想很简单,对于一般情况下单条语句…

使用c#制作一个小型桌面程序

封装dll 首先使用visual stdio 创建Dll新项目,然后属性管理器导入自己的工程属性表(如果没有可以参考visual stdio 如何配置opencv等其他环境) 创建完成后 系统会自动生成一些文件,其中 pch.cpp 先不要修改,pch.h中先导入自己需…