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,然后将其解码为字符。调用此方法后,ByteBuffer
的position
会被更新为limit
,因此如果你需要再次从缓冲区读取数据,你需要重置position
。- 使用
ByteBuffer.array()
方法将ByteBuffer
转换为字节数组然后构造String
实例的方法,虽然简单,但有其局限性。首先,它要求ByteBuffer
是基于数组的(即,它是由wrap
或allocateArray
等方法创建的),而且它会返回整个底层数组,而不仅仅是缓冲区中有效的字节部分。如果你知道缓冲区中的字节确实代表了一个完整的字符串,并且你知道字符集,那么这种方法是可行的,但通常不推荐这样做,因为它违反了封装原则。 - 在实际应用中,推荐使用
CharsetDecoder
或StandardCharsets.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);}}