Различные кодовые точки для одного и того же символа в MacOS и Windows - PullRequest
0 голосов
/ 31 октября 2018

У меня есть небольшой фрагмент кода, в котором я проверяю кодовую точку для символа Ü.

Locale lc = Locale.getDefault();
System.out.println(lc.toString());
System.out.println(Charset.defaultCharset());
System.out.println(System.getProperty("file.encoding"));
String inUnicode = "\u00dc";
String glyph = "Ü";
System.out.println("inUnicode " + inUnicode + " code point " + inUnicode.codePointAt(0));
System.out.println("glyph " + glyph + " code point " + glyph.codePointAt(0));

Я получаю другое значение для кодовой точки при запуске этого кода в MacOS x и Windows 10, см. Вывод ниже.

Вывод на MacOS

en_US
UTF-8
UTF-8
inUnicode Ü code point 220
glyph Ü code point 220

Вывод на Windows

en_US
windows-1252
Cp1252
in unicode Ü code point 220
glyph ?? code point 195

Я проверил кодовую страницу для windows-1252 на https://en.wikipedia.org/wiki/Windows-1252#Character_set, здесь кодовая точка для Ü равна 220. Для String glyph = "Ü"; почему я получаю кодовую точку как 195 в Windows? Насколько я понимаю, glyph должен был отображаться правильно, а кодовая точка должна была быть 220, поскольку она определена в Windows-1252.

Если я заменим String glyph = "Ü"; на String glyph = new String("Ü".getBytes(), Charset.forName("UTF-8"));, тогда glyph будет отображаться правильно и значение кодовой точки будет 220. Это правильный и эффективный способ стандартизировать поведение String в любой ОС независимо от локали и кодировки?

1 Ответ

0 голосов
/ 01 ноября 2018

195 - это 0xC3 в гексе.

В UTF-8 Ü кодируется как байты 0xC3 0x9C.

System.getProperty("file.encoding") говорит, что кодировкой файлов по умолчанию в Windows является не UTF-8, но ясно, что ваш Java-файл фактически кодируется в UTF-8. Тот факт, что println() выводит glyph ?? (примечание 2 ?, что означает наличие 2 char s), и что вы можете декодировать необработанные строковые байты, используя UTF-8 Charset, доказывает это .

glyph должен иметь один char со значением 0x00DC, а не 2 char с со значениями 0x00C3 0x009C. getCodepointAt(0) возвращает 0x00C3 (195) в Windows, потому что ваш Java-файл закодирован в UTF-8, но загружается так, как если бы он был закодирован в Windows-1252, поэтому 2 байта 0xC3 0x9C декодируются как символы 0x00C3 0x009C вместо символа 0x00DC.

Вам необходимо указать фактическую кодировку файла при запуске Java, например:

java -Dfile.encoding=UTF-8 ...
...