几天来,我一直在挠头,试图弄清楚如何正确编码用于文本字段的斯堪的纳维亚字符
这三个字符:ÆÅ(æøå)显示为���.意味着运行这个代码
System.out.println("øst");
打印"�st"。我不知道为什么。
这是我将System.out重定向到打印流的代码。
System.setProperty("user.language", "da");
OutputStream out = new OutputStream() {
@Override
public void write(int b) throws IOException {
appendConsole(new String(new byte[]{(byte)b}, "UTF-8"));
}
};
PrintStream ps;
try {
ps = new PrintStream(out, true, "UTF-8");
System.setOut(ps);
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(GameController.class.getName()).log(Level.SEVERE, null, ex);
}
如果有人能解决这个问题,我们将不胜感激!
尽量不要将int转换为字节或字符串,而是转换为char。这样行吗?
当这些字符被编码为UTF-8时,它们每个都需要两个字节。例如,UTF-8中的Æ是{ (byte) 0xc3, (byte) 0x86 }
。不能仅从其中一个字节构造字符串;这两个字节都需要组成一个有效的UTF-8序列。
您需要累积字节,直到您有足够的字节来形成完整的UTF-8序列,然后从中创建一个String。ByteBuffer和CharsetDecoder就是为此而设计的:
// A UTF-8 sequence for a single character is at most 4 bytes long.
private final ByteBuffer buffer = ByteBuffer.allocate(4);
private final CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
@Override
public void write(int b)
throws IOException {
buffer.put((byte) b);
int size = buffer.position();
int first = buffer.get(0) & 0xff;
if (size == 4 ||
(first >= 0xe0 && size == 3) ||
(first >= 0xc0 && size == 2) ||
first < 0x80) {
buffer.flip();
appendConsole(decoder.decode(buffer).toString());
buffer.clear();
}
}