Чтение 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. Таким образом, если ваш входной поток содержит астральные символы, они будут отображаться как суррогатная пара, т. Е. Как два char
s. Первый символ - высокий суррогат, а второй символ - низкий суррогат.
Хоть read()
определяется для возвращения int
и теоретически может вернуть кодовую точку дополнительного символа "все сразу", я считаю, что тип возвращаемого значения - только int
чтобы позволить значению -1 быть возвращенным.
Значение, которое вы получаете от read()
в основном char
под другим именем и Java char
ограничен 16 битами.
Java может представлять только дополнительные символы как суррогатную пару UTF-16, такого понятия, как "один символ", не существует (по крайней мере, в char
смысл), как только вы получите выше 0xFFFF, насколько это касается Java.