我正在尝试用Java解码一些UTF-8字符串。 这些字符串包含一些组合的unicode字符,例如CC 88(组合diaresis)。 根据{{3}}
,字符序列似乎没问题但转换为String后的输出无效。 有什么想法吗?
byte[] utf8 = { 105, -52, -120 };
System.out.print("{{");
for(int i = 0; i < utf8.length; ++i)
{
int value = utf8[i] & 0xFF;
System.out.print(Integer.toHexString(value));
}
System.out.println("}}");
System.out.println(">" + new String(utf8, "UTF-8"));
输出:
{{69cc88}} >i?
答案 0 :(得分:9)
您输出的控制台(例如Windows)可能不支持unicode,并且可能会破坏字符。控制台输出不是数据的良好表示。
尝试将输出写入文件,确保FileWriter上的编码正确,然后在unicode友好的编辑器中打开文件。
或者,使用调试器确保字符符合您的预期。只是不要相信控制台。
答案 1 :(得分:4)
代码很好,但正如skaffman所说,你的控制台可能不支持相应的角色。
要进行测试,您需要打印出字符的unicode值:
public class Test {
public static void main(String[] args) throws Exception {
byte[] utf8 = { 105, -52, -120 };
String text = new String(utf8, "UTF-8");
for (int i=0; i < text.length(); i++) {
System.out.println(Integer.toHexString(text.charAt(i)));
}
}
}
这打印69,308 - correct(U + 0069,U + 0308)。
答案 2 :(得分:4)
你是对的。谢谢!!
这里我最终在Windows上的Eclipse中解决了这个问题:
-Dfile.encoding=UTF-8
”我修改了代码如下:
byte[] utf8 = { 105, -52, -120 };
System.out.print("{{");
for(int i = 0; i < utf8.length; ++i)
{
int value = utf8[i] & 0xFF;
System.out.print(Integer.toHexString(value));
}
System.out.println("}}");
PrintStream sysout = new PrintStream(System.out, true, "UTF-8");
sysout.print(">" + new String(utf8, "UTF-8"));
输出:
{{69cc88}} > ï
谢谢!
答案 3 :(得分:1)
Java在将它们写入stdout
之前,将Unicode字符编码为本机系统编码的字节,并非不合理。某些操作系统,如许多Linux发行版,使用UTF-8
作为默认字符集,这很不错。
由于各种向后兼容性原因,Windows上的情况有所不同。默认的系统编码将是“ANSI”代码页之一,如果您打开默认命令提示符(cmd.exe),它将是旧的“OEM”DOS代码页之一(尽管它是可以在那里获得ANSI和Unicode {。{3}}。
由于U + 0308不在任何“ANSI”字符集中(在您的情况下可能为with a bit of work),因此它将被编码为错误字符(通常是问号)。
Unicode启用一切的替代方法是1252组合序列U + 0069 U + 0308到单个字符U + 00EF:
public static void emit(String foo) throws IOException {
System.out.println("Literal: " + foo);
System.out.print("Hex: ");
for (char ch : foo.toCharArray()) {
System.out.print(Integer.toHexString(ch & 0xFFFF) + " ");
}
System.out.println();
}
public static void main(String[] args) throws IOException {
String foo = "\u0069\u0308";
emit(foo);
foo = Normalizer.normalize(foo, Normalizer.Form.NFC);
emit(foo);
}
在windows-1252
下,此代码将发出:
Literal: i? Hex: 69 308 Literal: ï Hex: ef