0

几天来我一直在摸索,试图弄清楚如何正确编码斯堪的纳维亚字符以用于文本字段

这三个字符:Æ Ø Å ( æ ø å) 显示为 ��。意味着运行此代码

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);
    }

如果有人对此问题有解决方案,将不胜感激!

4

2 回答 2

0

尽量不要将 int 转换为字节转换为字符串,而是转换为 char。那样有用吗?

于 2015-12-08T12:14:30.223 回答
0

当这些字符被编码为 UTF-8 时,它们每个都需要两个字节。例如,UTF-8 中的 Æ 是{ (byte) 0xc3, (byte) 0x86 }. 您不能仅从一个字节构造字符串;两个字节都需要形成有效的 UTF-8 序列。

您需要累积字节,直到有足够的空间形成完整的 UTF-8 序列,然后从中创建一个字符串。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();
    }
}
于 2015-12-10T03:23:44.733 回答