Непоследовательное поведение Java при обработке utf-8 со строкой спецификации - PullRequest
1 голос
/ 21 марта 2019

Я открываю свой блокнот Windows, ввожу 18 и сохраняю файл в кодировке utf-8. Я знаю , что мой файл будет иметь заголовок спецификации, а мой файл представляет собой файл в кодировке utf-8 (с заголовком спецификации).

Проблема в том, что при печати этой строки с помощью кода ниже:

//str is that string read from the file using StandardCharsets.UTF_8 encoding
System.out.println(str);

В окнах я получил:

?18

Но в Linux я получил:

18

Так почему поведение Java отличается? Как это понять?

Ответы [ 2 ]

2 голосов
/ 21 марта 2019

Спецификация - это пространство нулевой ширины, поэтому в принципе невидимое.

Однако Window не имеет кодировки UTF-8, но использует одну из многих однобайтовых кодировок. Преобразование из String в вывод превратит спецификацию, отсутствующую в кодировке, в знак вопроса.

Still Notepad распознает спецификацию и отобразит текст UTF-8.

В настоящее время Linux обычно использует UTF-8, поэтому не имеет проблем и с консолью.


Дальнейшее объяснение

В Windows System.out использует консоль, и эта консоль, например, использует в качестве кодировки / кодировки, например, Cp-850, однобайтовую кодировку из примерно 256 символов. Пропущенный вполне может быть ĉ или символ спецификации. Если строка java содержит эти символы, они не могут быть закодированы в один из 256 доступных символов. Следовательно, они будут преобразованы в ?.

Использование CharsetEncoder :

String s = ...
CharsetEncoder encoder = Charset.defaultCharset().newEncoder();
if (!encoder.canEncode(s)) {
    System.out.println("A problem");
}

Windows обычно также работает с однобайтовой кодировкой, например Cp-1252. Опять 256 символов. Однако редакторы могут иметь дело с несколькими кодировками, и если шрифт может представлять символ (кодовая точка Unicode), то все работает.

0 голосов
/ 21 марта 2019

Поведение Java такое же, FileInputStream не обрабатывать BOM.

В Windows ваш файл file1, шестнадцатеричный файл1 присутствует EF BB BF 31 38

В linux ваш файл file2, шестнадцатеричный файл file2 - 31 38

когда вы читаете их, вы получите другую строку.

Я рекомендую вам преобразовать файл BOM в файл без BOM с помощью блокнота ++.

Или вы можете использовать BOMInputStream

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...