Octal Escape в Java приводят к неправильному значению байта, проблема с кодировкой? - PullRequest
2 голосов
/ 23 октября 2010

Согласно этой документации (http://java.sun.com/docs/books/jls/third_edition/html/lexical.html, 3.10.6) OctalEscape будет преобразован в символ Unicode.Теперь у меня есть проблема, что следующий код приведет к 2-байтовому символу Unicode с неверной информацией.

for (byte b : "\222".getBytes()) {
     System.out.format("%02x ", b);
}

Результат - "c2 92".Я объяснил только «92», потому что это будет преобразованное значение из 222 восьмеричного в гекс (92).Если я проверю это с символом, информация о байтах будет правильной.

System.out.format("%02x ", (byte)'\222');

Результат - «92» для одного байта ». Моя кодировка по умолчанию -« UTF-8 »в Linux с Java / c 1.6.0_18.

История моего вопроса в том, что я ищу метод для преобразования восьмеричной строки из входной кодировки Cp1252 в UTF-8. Это не удается из-за преобразования восьмеричной строки с экранированиемдо 2 байтов. Кто-нибудь знает, почему в массив char всегда добавляется дополнительный байт "c2"? Простой подсчет показывает, что в массиве есть только один символ.

System.out.println("\222".toCharArray().length); // will result in "1"

Спасибодля ваших подсказок.

Обновление: Как упомянул BalusC, восьмеричное экранированное значение интерпретируется как значение UTF-8, что приводит к проблеме. Пока это значение сохраняется в исходном коде (UTF-8)нет возможности читать в этой строке с другой кодировкой. Я прав? Если я читаю файл в кодировке Cp1252, я должен объявить кодировку InputReader с правильной кодировкой и выполнить кодировку дляUTF-8 для обработки и сохранения прочитанного содержимого как UTF-8.

Ответы [ 2 ]

4 голосов
/ 23 октября 2010

В вызове String#getBytes() без указанной кодировки будет использоваться кодировка платформы по умолчанию для преобразования символов в байты. Поскольку c2 - это типичный первый байт двухбайтового символа многобайтовой последовательности UTF-8 , вы, очевидно, используете UTF-8 в качестве кодировки по умолчанию для платформы. Если вы хотите получить байты CP1252, вам нужно явно указать это в методе String#getBytes(String charsetName).

for (byte b : "\222".getBytes("cp1252")) {
     System.out.format("%02x ", b);
}

Обновление согласно вашему обновлению:

Пока это значение сохраняется в исходном коде (UTF-8), у меня нет возможности читать эту строку с другой кодировкой. Я прав?

Это верно. Вам необходимо прочитать файл в той же кодировке, в которой он был сохранен, в противном случае вы рискуете получить mojibake .

Если я читаю файл в кодировке Cp1252, я должен объявить кодировку InputReader с правильным набором символов и выполнить кодировку в UTF-8 для обработки и сохранения прочитанного содержимого как UTF-8.

Просто прочитайте файл как CP1252, используя InputStreamReader. При чтении в виде символов (строк) Java будет неявно хранить его как Unicode (UTF-16). Вы можете обрабатывать данные как Unicode. Нет необходимости вводить промежуточный шаг файла UTF-8. Если вы хотите сохранить файл, используйте OutputStreamWriter с нужной кодировкой, это может отличаться от CP1252. Только помните, что любой символ, не охваченный кодировкой, в конечном итоге получит ?.

Смотри также:

3 голосов
/ 23 октября 2010

Все символы и строки в Java имеют формат UTF-16. Итак, вы ввели управляющий символ U + 0092 PRIVATE USE TWO и закодировали его в UTF-8 (этот символ занимает два байта при кодировании как UTF-8). Символы, закодированные как что-либо кроме UTF-16, должны быть представлены байтовыми массивами.

U + 2019: & # x2019;

Полагаю, вы намереваетесь перекодировать символ U + 2019 ПРАВАЯ ОДНОКВАЖНАЯ МАРКА ЦИТАТЫ . В Windows-1252 это значение байта равно 92. Ненавижу разочаровывать, но когда кодируется как UTF-8, это заканчивается многобайтовой последовательностью E2 80 99.

Также обратите внимание, что U + 2019 не может быть представлен восьмеричной escape-последовательностью в Java, так как он имеет значение выше U + 00FF. Вы должны будете использовать escape-последовательность Unicode \u2019. Я написал сообщение в блоге о транскодировании на разных языках здесь и кодировании в исходных файлах Java здесь .

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