Java:String 与 ByteBuffer 的相互转换及相关问题 [英] Java: Converting String to and from ByteBuffer and associated problems
问题描述
我的套接字连接使用 Java NIO,我的协议是基于文本的,所以我需要能够在将字符串写入 SocketChannel 之前将它们转换为 ByteBuffers,并将传入的 ByteBuffers 转换回字符串.目前,我正在使用此代码:
I am using Java NIO for my socket connections, and my protocol is text based, so I need to be able to convert Strings to ByteBuffers before writing them to the SocketChannel, and convert the incoming ByteBuffers back to Strings. Currently, I am using this code:
public static Charset charset = Charset.forName("UTF-8");
public static CharsetEncoder encoder = charset.newEncoder();
public static CharsetDecoder decoder = charset.newDecoder();
public static ByteBuffer str_to_bb(String msg){
try{
return encoder.encode(CharBuffer.wrap(msg));
}catch(Exception e){e.printStackTrace();}
return null;
}
public static String bb_to_str(ByteBuffer buffer){
String data = "";
try{
int old_position = buffer.position();
data = decoder.decode(buffer).toString();
// reset buffer's position to its original so it is not altered:
buffer.position(old_position);
}catch (Exception e){
e.printStackTrace();
return "";
}
return data;
}
这在大多数情况下都有效,但我怀疑这是否是执行此转换的每个方向的首选(或最简单)方法,或者是否有另一种尝试方法.偶尔,而且似乎是随机的,对 encode()
和 decode()
的调用会抛出一个java.lang.IllegalStateException: Current state = FLUSHED, new state = CODING_END
异常或类似,即使每次转换完成时我都使用新的 ByteBuffer 对象.我需要同步这些方法吗?在 Strings 和 ByteBuffers 之间转换的任何更好的方法?谢谢!
This works most of the time, but I question if this is the preferred (or simplest) way to do each direction of this conversion, or if there is another way to try. Occasionally, and seemingly at random, calls to encode()
and decode()
will throw a
java.lang.IllegalStateException: Current state = FLUSHED, new state = CODING_END
exception, or similar, even if I am using a new ByteBuffer object each time a conversion is done. Do I need to synchronize these methods? Any better way to convert between Strings and ByteBuffers? Thanks!
推荐答案
查看CharsetEncoder
和 CharsetDecoder
API 描述 - 您应该遵循特定的方法调用顺序以避免此问题.例如,对于 CharsetEncoder
:
Check out the CharsetEncoder
and CharsetDecoder
API descriptions - You should follow a specific sequence of method calls to avoid this problem. For example, for CharsetEncoder
:
- 通过
reset
方法重置编码器,除非之前没有使用过; - 调用
encode
方法零次或多次,只要额外的输入可用,为 endOfInput 参数传递false
并填充输入缓冲区并刷新输出调用之间的缓冲区; - 最后一次调用
encode
方法,为 endOfInput 参数传递true
;然后 - 调用
flush
方法,以便编码器可以将任何内部状态刷新到输出缓冲区.
- Reset the encoder via the
reset
method, unless it has not been used before; - Invoke the
encode
method zero or more times, as long as additional input may be available, passingfalse
for the endOfInput argument and filling the input buffer and flushing the output buffer between invocations; - Invoke the
encode
method one final time, passingtrue
for the endOfInput argument; and then - Invoke the
flush
method so that the encoder can flush any internal state to the output buffer.
顺便说一下,这与我在 NIO 上使用的方法相同,尽管我的一些同事在他们只使用 ASCII 的知识中将每个字符直接转换为一个字节,我可以想象这可能会更快.
By the way, this is the same approach I am using for NIO although some of my colleagues are converting each char directly to a byte in the knowledge they are only using ASCII, which I can imagine is probably faster.
这篇关于Java:String 与 ByteBuffer 的相互转换及相关问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!