Получить доступ

Чем байтовые потоки отличаются от символьных?

JuniorВвод-вывод и NIO
Ещё спрашивают так:
  • Чем InputStream отличается от Reader?
  • Почему важно указывать кодировку при чтении файла?
Коротко

Байтовые потоки (InputStream/OutputStream) — для любых двоичных данных, символьные (Reader/Writer) — для текста и учитывают кодировку.

  • Символ и байт — не одно и то же: в UTF-8 буква занимает 1–4 байта
  • Мост между мирами — InputStreamReader / OutputStreamWriter с явной кодировкой

А ещё Кодировку указывайте явно; с Java 18 по умолчанию UTF-8, раньше — системная

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

В Java две иерархии классов ввода-вывода:

  • байтовые — InputStream и OutputStream: читают и пишут байты. Для картинок, архивов, сетевых протоколов, любых двоичных данных;
  • символьные — Reader и Writer: работают с символами и превращают байты в символы по кодировке.

Разделение нужно, потому что символ и байт — разные вещи. В UTF-8 латиница занимает один байт, кириллица — два, эмодзи — четыре. Если читать текст байтами кусками и превращать каждый кусок в строку, многобайтовые символы разрежутся на границах — получатся «кракозябры».

Мост между мирами — InputStreamReader и OutputStreamWriter, которым передают кодировку. Буферизация (BufferedReader) ускоряет чтение и даёт readLine().

Кодировку стоит указывать явно (StandardCharsets.UTF_8). До Java 18 по умолчанию бралась кодировка системы, и одна и та же программа читала файл по-разному на Windows и Linux. С Java 18 по умолчанию UTF-8.

Для простых задач удобны Files.readString, Files.readAllLines, Files.newBufferedReader.

Пример

try (var reader = Files.newBufferedReader(Path.of("users.csv"), StandardCharsets.UTF_8)) {
    String line;
    while ((line = reader.readLine()) != null) { process(line); }
}

byte[] image = Files.readAllBytes(Path.of("logo.png")); // двоичные данные

Что хотят услышать

  • Байтовые для двоичных данных, символьные для текста.
  • Почему важна кодировка и что ломается без неё.
  • Мост InputStreamReader и явное указание кодировки.

Частые ошибки

  • Читать текст побайтово и разрезать многобайтовые символы.
  • Не указывать кодировку явно.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓Байтовые работают с произвольными двоичными данными, символьные — с текстом и учитывают кодировку
  • ✗Байтовые работают быстрее, но теряют часть данных
  • ✗Символьные предназначены только для консоли
  • ✗Байтовые доступны только для чтения

Что спросят дальше

  • Зачем нужна буферизация при чтении?
  • Чем опасна кодировка по умолчанию?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем