Чтение Java в символьных потоках с дополнительными символами юникода - PullRequest
2 голосов
/ 11 октября 2011

У меня проблемы с чтением дополнительных символов Юникода с использованием Java. У меня есть файл, который потенциально содержит символы в дополнительном наборе (что-нибудь больше, чем \ uFFFF). Когда я настроил свой InputStreamReader для чтения файла с использованием UTF-8, я ожидал, что метод read () будет возвращать по одному символу для каждого дополнительного символа, вместо этого он кажется разделенным на 16-битный порог.

Я видел некоторые другие вопросы о базовых символьных потоках Юникода, но, похоже, ничто не имеет отношения к более чем 16-битному случаю.

Вот несколько упрощенных примеров кода:

InputStreamReader input = new InputStreamReader(file, "UTF8");
int nextChar = input.read();
while(nextChar != -1) {
    ...
    nextChar = input.read();
}

Кто-нибудь знает, что мне нужно сделать, чтобы правильно прочитать файл в кодировке UTF-8, содержащий дополнительные символы?

Ответы [ 2 ]

4 голосов
/ 11 октября 2011

Java работает с UTF-16 . Таким образом, если ваш входной поток имеет астральные символы, они будут отображаться в виде суррогатной пары, то есть двух char с. Первый символ - верхний суррогат, второй - низкий суррогат.

1 голос
/ 11 октября 2011

Хотя read() определено так, чтобы возвращать int, и теоретически может возвращать кодовую точку дополнительного символа "все сразу", я считаю, что тип возвращаемого значения - только int, что позволяет возвращать значение -1 .

Значение, которое вы получаете от read(), это в основном char под другим именем, а Java * char ограничено 16 битами.

Java может представлять дополнительные символы только как суррогатную пару UTF-16, не существует такого понятия, как «одиночный символ» (по крайней мере, в смысле char), как только вы достигнете 0xFFFF, насколько это касается Java.

...