Подтвердить что ты не робот

Разница между InputStream и InputStreamReader при чтении многобайтовых символов

Разница между InputStream и InputStreamReader заключается в том, что InputStream читается как byte, а InputStreamReader читается как char. Например, если текст в файле abc, то оба они работают нормально. Но если текст a你们, который состоит из a и двух китайских символов, то InputStream не работает.

Итак, мы должны использовать InputStreamReader, но мой вопрос:

Как InputStreamReader распознать символы?

a - один байт, но китайский символ - два байта. Прочитал ли он a как один байт и распознал другие символы как два байта или для каждого символа в этом тексте, читает ли он InputStreamReader как два байта?

4b9b3361

Ответ 1

An InputStream считывает необработанные октетные (8-битные) данные. В Java тип byte эквивалентен типу char в C. В C этот тип может использоваться для представления символьных данных или двоичных данных. В Java тип char имеет большее сходство с типом C wchar_t.

An InputStreamReader затем преобразует данные из некоторой кодировки в UTF-16. Если "a 你们" закодирован как UTF-8 на диске, это будет последовательность байтов 61 E4 BD A0 E4 BB AC. Когда вы передаете InputStream в InputStreamReader с кодировкой UTF-8, она будет считана как последовательность char 0061 4F60 4EEC.

API кодировки символов в Java содержит алгоритмы для выполнения этого преобразования. Вы можете найти список кодировок, поддерживаемых Oracle JRE здесь. ICU project - хорошее место для начала, если вы хотите понять внутренности того, как это работает на практике.

Как указывает Александр Погребняк , вы почти всегда должны предоставлять кодировку явно. byte -to- char, которые не указывают кодировку, полагаются на JRE default, который зависит от операционных систем и пользователя настройки.

Ответ 2

Вам нужно дать подсказку читателю, указав набор символов, в котором записано двоичное файл. Например:

Reader reader =
   new InputStreamReader(
       new FileInputStream( "/path/to/file" ),
       "UTF-8" // most likely that the encoding of the file
   )

Без подсказки он будет использовать кодировку по умолчанию для платформы, которая во многих случаях не является тем, что вы хотите.

Эта ссылка имеет хорошее объяснение кодировок: http://www.joelonsoftware.com/articles/Unicode.html