Gymterview
junior

Какие классы позволяют преобразовать байтовые потоки в символьные и обратно?

Преобразование между байтовыми и символьными потоками выполняют два класса-моста из пакета java.io.

OutputStreamWriter — мост от символьного потока к байтовому. Принимает OutputStream и преобразует символы (char) в байты при записи, используя указанную кодировку. Если кодировка не указана, используется кодировка по умолчанию системы.

InputStreamReader — мост от байтового потока к символьному. Принимает InputStream и преобразует байты в символы (char) при чтении, используя указанную кодировку.

Пример с явным указанием кодировки

Пример
// Чтение: байтовый поток -> символьный
try (Reader reader = new InputStreamReader(
        new FileInputStream("data.txt"), StandardCharsets.UTF_8)) {
    int ch;
    while ((ch = reader.read()) != -1) {
        System.out.print((char) ch);
    }
}

// Запись: символьный поток -> байтовый
try (Writer writer = new OutputStreamWriter(
        new FileOutputStream("output.txt"), StandardCharsets.UTF_8)) {
    writer.write("Текст в UTF-8");
}

На практике явное указание кодировки критически важно для кроссплатформенных приложений. Без указания кодировки Java использует системную кодировку по умолчанию, которая может различаться между ОС (UTF-8 на Linux, Windows-1251 на Windows), что приводит к искажению текста.

Классы FileReader и FileWriter до Java 11 были просто обёртками над InputStreamReader/OutputStreamWriter с кодировкой по умолчанию. Начиная с Java 11 у них появились конструкторы, принимающие Charset.

На собеседовании: назовите два класса-моста и подчеркните важность явного указания кодировки. Распространённая ошибка — полагаться на системную кодировку.