在Java中,如何将字符表示为字节

24

我需要把一个char转换成byte或byte数组。在其他语言中,我知道char只是一个字节。然而,查看Java的Character类,其最小值为 \u0000,最大值为 \uFFFF。这似乎表明一个char的长度为2个字节。

我能将其存储为一个byte吗,还是需要将其存储为两个字节?

在任何人问之前,我要说我正在尝试这样做,因为我正在使用期望结果为byte数组的接口。所以我必须将我的char转换为一个byte数组。

请告诉我并帮助我理解这一点。

谢谢, jbu

4个回答

35
要将字符转换为字节,您需要指定字符编码。一些字符编码每个字符使用一个字节,而其他编码使用两个或更多字节。实际上,对于许多语言,有太多字符无法用单个字节进行编码。
在Java中,将字符转换为字节的最简单方法是使用String类的getBytes(Charset)方法。(StandardCharsets类定义了一些常见编码。)但是,如果该字符在指定的编码下无法映射,则此方法将悄悄地将字符替换为�。如果您需要更多控制,则可以配置CharsetEncoder以处理此情况,并使用错误或使用不同的替换字符。

1
使用UTF-8并将字符存储为单个字节是否可以? 我认为可以,即使最后一位是字节的符号位。 - jbu
你应该使用与你所工作的界面所需的字符编码。 - erickson
1
对于单字节编码,请使用ISO-8859系列。 - Shimi Bandiel
我们正在使用UTF-8,所以我想知道是否可以只进行字符->字节转换。 - jbu
2
不,如果您正在使用UTF-8,并且有任何非ASCII字符(char值> 127),则应使用编码API将其转换为字节。在UTF-8中,非ASCII字符需要两个或更多字节。如果您只是将范围在128-255之间的字符强制转换为字节,则会解码错误的字符。 - erickson
1
使用 "this string".getBytes("utf-8"); - Seun Osewa

9

在Java中,char确实是16位(也是唯一的无符号类型!!)。

如果您确定字符的编码为ASCII,则可以将它们强制转换为字节(因为ASCII仅使用char的低7位)。

如果您不需要修改字符或了解它们在字符串中的含义,则可以将字符存储在两个字节中,例如:

char[] c = ...;
byte[] b = new byte[c.length*2];
for(int i=0; i<c.length; i++) {
    b[2*i] = (byte) (c[i]&0xFF00)>>8; 
    b[2*i+1] = (byte) (c[i]&0x00FF); 
}

如果速度很重要,建议将2*替换为右移。

然而,请注意有些实际(显示的)字符(或更准确地说是Unicode代码点)写在两个连续的字符上。因此,在两个字符之间切割并不保证你正在切割实际字符之间。

如果您需要以String感知的方式解码/编码或以其他方式操作char数组,则应尝试使用java.io工具解码和编码char数组或String,以确保正确的字符操作。


与其使用此处显示的代码,请将字符编码指定为“UTF-16”并使用内置的编码API。这样可以减少您需要实现、测试和维护的代码量,并且更清晰地捕捉代码读者的意图。 - erickson
同时速度也要慢两个数量级,因为需要进行编码/解码,而在这种情况下可能并不需要。 - Varkhan
这只是编码问题,如果有任何减慢(我怀疑),也不会超过100倍。你为什么认为UTF-16编码与你的代码有显着不同的地方呢? - erickson
因为我已经读过Sun的代码,它使用了整个nio机制,这显着慢了很多。经过基准测试,实际因素在30到50之间(是的,对于我的应用程序来说,这很重要)。 - Varkhan
哦,我忘了提到......解码器不是线程安全的。但这是另外一个故事...... - Varkhan

4

为了扩展其他人所说的,如果您有一个需要作为字节数组的字符,那么您首先要创建一个包含该字符的字符串,然后从字符串中获取字节数组:

private byte[] charToBytes(final char x) {
  String temp = new String(new char[] {x});
  try {
    return temp.getBytes("ISO-8859-1");
  } catch (UnsupportedEncodingException e) {
    // Log a complaint
    return null;
  }
}

当然,使用适当的字符集。更加高效的方法是使用字符串而不是逐个字符地转换为字符串,然后再转换为字节数组。


0

Java中的char是一个无符号16位值。如果你所拥有的内容只需要7位就可以存储,那么可以将其转换为byte类型(例如ASCII码可以存储在byte类型中)。

你也可以查看java.nio.charset API。


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