Ключевой концепцией здесь является кодировка символов : каждый читаемый человеком символ каким-то образом кодируется в один или несколько байтов. Есть много кодировок символов. Самые популярные из них:
- ASCII (7 бит, оставшийся бит не используется), который обрабатывает один символ как один байт
- UTF-8: наиболее распространенные символы представлены в виде одного байта, менее распространены как 2 или даже больше
Эти кодировки доступны для чтения даже при открытии файла в шестнадцатеричном редакторе. Однако существует много кодировок символов, которые не имеют этой функции, а именно UTF-16 и UTF-32.
Теперь вернемся к вашему вопросу: InputStream
дает вам только поток байтов. Если ваши байты представляют собой символы, закодированные с помощью ASCII или UTF-8, большую часть времени у вас все в порядке. Но если эти байты представляют что-то более сложное, например, UTF-16, вам абсолютно необходим Reader
. Конечно, читатель должен знать, какую кодировку символов обеспечивает базовый InputStream
. Это часто проблема, которую делают новички - Reader
, не инициализированный явным образом с помощью кодировки символов, часто возвращается к системному значению по умолчанию.
Другой способ (с писателями) аналогичен. Если вы просто преобразуете свои char
s в byte
s, большую часть времени у вас все будет хорошо. Но если ваши символы содержат менее популярные национальные буквы, ваш вывод будет искажен / усечен. Таким образом, вы создаете Writer
, который преобразует каждый данный символ в серию из одного или нескольких байтов. Еще раз вы обязаны предоставить кодировку символов.
Важные правила:
- всегда используйте
InputStream
при работе с двоичными данными (мультимедиа, файлы ZIP и PDF и т. Д.)
- всегда использовать
Reader
при чтении текста (txt, HTML, XML ...)
- всегда знать и указывать кодировку символов при чтении символа из потока байтов, всегда сознательно выбирать кодировку символов, которую вы используете для записи данных.