Чтение Java в символьных потоках с дополнительными символами юникода

У меня проблемы с чтением дополнительных символов Юникода с использованием 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 ответа

Решение

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

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

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

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

Другие вопросы по тегам