如何将 java.nio.ByteBuffer 转为 String

如何将 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)

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()

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);

        // 将字节数据放入ByteBuffer
        ByteBuffer 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

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

测试用例

测试1

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);
		
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kfepiza

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值