Какие классы позволяют преобразовать байтовые потоки в символьные и обратно?
Преобразование между байтовыми и символьными потоками выполняют два класса-моста из пакета 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.
На собеседовании: назовите два класса-моста и подчеркните важность явного указания кодировки. Распространённая ошибка — полагаться на системную кодировку.