Java ByteBuffer转换为String

这是一个正确的方法来将ByteBuffer转换为String,

String k = "abcd"; ByteBuffer b = ByteBuffer.wrap(k.getBytes()); String v = new String(b.array()); if(k.equals(v)) System.out.println("it worked"); else System.out.println("did not work"); 

我问的原因是这看起来太简单了,而像Java这样的其他方法:将string转换为ByteBuffer以及从相关的问题看起来更复杂。

如果您知道字节在平台的默认字符集中,您的方法将是合理的。 在你的例子中,这是真的,因为k.getBytes()返回平台的默认字符k.getBytes()的字节。

更频繁的是,你需要指定编码。 但是,有一个比你连接的问题更简单的方法。 stringAPI提供了以特定编码在string和byte []数组之间进行转换的方法。 当需要对解码[编码]过程进行更多的控制时,这些方法build议使用CharsetEncoder / CharsetDecoder 。“

 import java.nio.charset.Charset; 

要以特定的编码方式从string中获取字节,可以使用兄弟的getBytes()方法:

 byte[] bytes = k.getBytes( Charset.forName("UTF-8" )); 

要将具有特定编码的字节放入String中,可以使用不同的String构造函数:

 String v = new String( bytes, Charset.forName("UTF-8") ); 

请注意, ByteBuffer.array()是一个可选的操作。 如果你已经用数组构造了你的ByteBuffer,你可以直接使用这个数组。 否则,如果您想要安全,请使用ByteBuffer.get(byte[] dst, int offset, int length)将缓冲区中的字节转换为字节数组。

编辑

作为一个侧面的问题,在上面的示例代码中,对Charset.forName("UTF-8")的调用应该适用于1.4以来的所有Java版本。

如果您使用Java 7或更高版本 ,则可以使用java.nio.charset.StandardCharsets.UTF_8(BenKirby在他的评论中注明了这一点)

如果您使用Guava ,则可以使用com.google.common.base.Charsets.UTF_8(在下面的评论中用spacecamel注明)

Andy Thomas提到,将ByteBuffer解码为String没有任何问题。

 String s = StandardCharsets.UTF_8.decode(byteBuffer).toString(); 

尝试这个:

 new String(bytebuffer.array(), "ASCII"); 

NB。 你不能正确地转换一个字节数组到一个string,而不知道它的编码。

我希望这有帮助

只是想指出,假设ByteBuffer.array()将始终工作是不安全的。

 byte[] bytes; if(buffer.hasArray()) { bytes = buffer.array(); } else { bytes = new byte[buffer.remaining()]; buffer.get(bytes); } String v = new String(bytes, charset); 

通常,根据您的使用情况,buffer.hasArray()将始终为true或false。 在实践中,除非您真的希望在任何情况下都能正常工作,否则优化您不需要的分支是安全的。 但其余的答案可能无法使用通过ByteBuffer.allocateDirect()创build的ByteBuffer。

引用简单调用array()的答案是不正确的:当缓冲区已被部分使用,或者引用数组的一部分时(您可以ByteBuffer.wrap数组在给定的偏移量,不一定从头开始) ,我们在计算中必须考虑到这一点。 这是在所有情况下都适用于缓冲区的通用解决scheme(不包括编码):

 if (myByteBuffer.hasArray()) { return new String(myByteBuffer.array(), myByteBuffer.arrayOffset() + myByteBuffer.position(), myByteBuffer.remaining()); } else { final byte[] b = new byte[myByteBuffer.remaining()]; myByteBuffer.duplicate().get(b); return new String(b); } 

对于与编码有关的问题,请参阅Andy Thomas的回答。

将string转换为ByteBuffer,然后从ByteBuffer转换回使用Java的string:

 import java.nio.charset.Charset; import java.nio.*; String babel = "obufscate thdé alphebat and yolo!!"; System.out.println(babel); //Convert string to ByteBuffer: ByteBuffer babb = Charset.forName("UTF-8").encode(babel); try{ //Convert ByteBuffer to String System.out.println(new String(babb.array(), "UTF-8")); } catch(Exception e){ e.printStackTrace(); } 

其中首先打印打印的裸露string,然后将ByteBuffer转换为array():

 obufscate thdé alphebat and yolo!! obufscate thdé alphebat and yolo!! 

这也对我有帮助,将string减less到原始字节可以帮助检查发生了什么:

 String text = "こんにちは"; //convert utf8 text to a byte array byte[] array = text.getBytes("UTF-8"); //convert the byte array back to a string as UTF-8 String s = new String(array, Charset.forName("UTF-8")); System.out.println(s); //forcing strings encoded as UTF-8 as an incorrect encoding like //say ISO-8859-1 causes strange and undefined behavior String sISO = new String(array, Charset.forName("ISO-8859-1")); System.out.println(sISO); 

将您的string打印为UTF-8,然后再打印为ISO-8859-1:

 こんにちはããã«ã¡ã¯ 

注意(除了编码问题),一些更复杂的链接代码会导致所讨论的ByteBuffer的“活动”部分(例如通过使用位置和限制),而不是简单地编码所有的字节在整个支持数组(如这些答案中的许多例子)。