在 Java 中将 ByteBuffer 转换为字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29190684/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert ByteBuffer to String in Java
提问by Liam de Haas
I have a byte[] bytes
from a ByteBuffer
which contains a packet. I want to put the packet in a String
.
我有一个byte[] bytes
from a ByteBuffer
,其中包含一个数据包。我想把数据包放在一个String
.
Currently I have the following
目前我有以下
byte[] bytes = packet.array();
System.out.println("Packet String:" + new String(bytes));
But then I end up with the following output
但后来我得到了以下输出
Packet String:E????<?@??@?.
03-22 04:30:28.187 9296-10152/willem.com.vpn I/System.out﹕ ????J}?j???k?:??????????9???????
03-22 04:30:28.197 9296-10152/willem.com.vpn I/System.out﹕ ??&?4????????ddrarpa??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
I've tried it with encoding like this
我已经用这样的编码试过了
System.out.println("Packet String:" + new String(bytes, Charset.forName("UTF-8")));
But that isn't the right charset. Can anybody tell me what is?
但这不是正确的字符集。谁能告诉我是什么?
回答by kuujo
You need to use the buffer's position and limit to determine the number of bytes to read.
您需要使用缓冲区的位置和限制来确定要读取的字节数。
// ...populate the buffer...
buffer.flip(); // flip the buffer for reading
byte[] bytes = new byte[buffer.remaining()]; // create a byte array the length of the number of bytes written to the buffer
buffer.get(bytes); // read the bytes that were written
String packet = new String(bytes);
In my opinion you shouldn't really be using the backing array()
at all; it's bad practice. Direct byte buffers (created by ByteBuffer.allocateDirect()
won't have a backing array and will throw an exception when you try to call ByteBuffer.array()
. Because of this, for portability you should try to stick to the standard buffer get
and put
methods. Of course, if you really want to use the array you can use ByteBuffer.hasArray()
to check if the buffer has a backing array.
在我看来,您根本不应该真正使用支持array()
;这是不好的做法。直接字节缓冲区(由创建的ByteBuffer.allocateDirect()
不会有后备数组,并且在您尝试调用时会抛出异常ByteBuffer.array()
。因此,为了可移植性,您应该尝试坚持标准缓冲区get
和put
方法。当然,如果您真的想要使用可用于ByteBuffer.hasArray()
检查缓冲区是否有支持数组的数组。
回答by Alex Yarmula
The answer talking about setting range from position to limit is not correct in a general case. When the buffer has been partially consumed, or is referring to a part of an array (you can ByteBuffer.wrap
an array at a given offset, not necessarily from the beginning), we have to account for that in our calculations. This is the general solution that works for buffers in all cases (does not cover encoding):
谈论从位置到限制的设置范围的答案在一般情况下是不正确的。当缓冲区被部分消耗,或者指的是数组的一部分(你可以ByteBuffer.wrap
在给定的偏移量处创建一个数组,不一定从头开始),我们必须在计算中考虑到这一点。这是适用于所有情况下的缓冲区的通用解决方案(不包括编码):
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);
}
For the concerns related to encoding, see Andy Thomas' answer.
有关与编码相关的问题,请参阅 Andy Thomas 的回答。
回答by user207421
You're ignoring the limit
of the buffer. You should flip()
the buffer, then call
您忽略limit
了缓冲区的 。你应该flip()
缓冲,然后调用
new String(buffer.array(), 0, buffer.position())
Then reset it.
然后重置它。
But you should really be using a Charset
decoder to yield a CharBuffer
for this. At least you should specify a character set to the String
constructor.
但是你真的应该使用Charset
解码器来为此产生一个CharBuffer
。至少你应该为String
构造函数指定一个字符集。