有没有一种简单的方法将一个字节追加到StringBuffer并指定编码方式?

11

问题

如何以最简单的方式将字节附加到StringBuffer中(即将一个字节转换为字符),并指定所使用的字符编码(ASCII,UTF-8等)?

背景

我想将一个字节追加到stringbuffer中。这需要将字节强制转换为字符:

myStringBuffer.append((char)nextByte);

然而,上述代码使用了我的机器的默认字符编码(即MacRoman)。与此同时,系统/网络中的其他组件需要UTF-8。因此,我需要进行以下操作:

try {
    myStringBuffer.append(new String(new Byte[]{nextByte}, "UTF-8"));
} catch (UnsupportedEncodingException e) {
    //handle error
}

说实话,这样做相当丑陋。

肯定有更好的方法(而不是将同一代码分成多行)吧?????


有点偏题,Java 5+中使用StringBuilder代替StringBuffer。除非你知道为什么需要一个StringBuffer(内部同步),否则与StringBuilder相比,你不需要它,因为它的操作和方法是相同的,但它总是更快。 - pickypg
2个回答

16

简短的回答是'不行'。如果这个字节是多字节序列的第一个字节,那么没有东西能够维持状态。

如果你手头上有逻辑字符的所有字节,则可以执行以下操作:

sb.append(new String(bytes, charset));

如果你有一个UTF-8字节,使用标准类是无法完成此操作的。

构建一个使用java.nio.charset类实现字节追加的增强StringBuffer并不是非常困难,但这不是一两行代码就能解决的问题。

注释需要基本的Unicode知识。

在UTF-8中,'a'占用一个字节,'á'占用两个字节,'丧'占用三个字节,''占用四个字节。 CharsetDecoder的工作是将这些序列转换为Unicode字符。从字节的顺序操作来看,这显然是一个有状态的过程。

如果您为UTF-8创建一个CharsetDecoder,您只能通过这个方法逐个字节(在ByteBuffer中)输入数据。UTF-16字符将累积到输出的CharBuffer中。


是的。ASCII字符由单个字节表示,而非ASCII字符由2、3或4个字节表示。 - dan04
1
如果它们只是ASCII,那么你应该使用一个帮助方法来捕获异常。public static String bytesToUsAscii(byte[] bytes) { try { return new String(bytes, "US-ASCII"); } catch (UnsupportedEncodingException e) { throw new IllegalStateException(e); } }。JVM保证US-ASCII是受支持的字符编码(以及UTF-8和UTF-16),因此除非出现严重问题,否则永远不会发生异常。 - pickypg
没有更强的证据,我不愿意假设OP真的在处理ISO-646。他/她明确提到UTF-8而不是ASCII。 @pic @dan - bmargulies
1
@pick 然后读他的第二句话,看看你是否像我一样摇晃。 - bmargulies
@bmargulies/pickypg:谢谢大家。简单的答案是“不”,没有更容易解决这个问题的方法。我成功地保证我们只用ASCII处理,所以我把所有UTF-8的引用都改成了ASCII;然而,这个过程仍然涉及到很尴尬的语法以及没有意义的try/catch语句,因为它肯定永远不会出错。因此我只是通过切面软化/交叉处理,并称之为一天! - gMale
显示剩余4条评论

4
我认为这里的错误在于处理字节。你应该处理字符串而不是字节。
只需在输入和输出流上插入一个读取器,以便为您执行字节和字符之间的映射。对于输入,请使用InputStreamReader(InputStream in, CharsetDecoder dec)构造函数形式,以便您可以通过异常检测输入编码错误。现在,您拥有的是字符串而不是字节缓冲区。在另一端放置一个OutputStreamWriter
现在,您不再需要担心字节或编码。这样做更简单。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接