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