← Назад к вопросам

В чем разница между InputStream и Reader?

1.3 Junior🔥 241 комментариев
#ООП#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Разница между InputStream и Reader в Java

Оба класса используются для чтения данных, но работают на разных уровнях абстракции:

Краткая таблица

АспектInputStreamReader
Что читаетСырые байты (0-255)Символы (0-65535)
Возвращаетint (0-255 или -1)int (символ код или -1)
Размер данных8 бит (1 байт)16 бит (2 байта)
КодировкаОтсутствуетUTF-8, UTF-16 и т.д.
ДляБинарные файлыТекстовые файлы
ПодклассыFileInputStreamFileReader
ОбёрткиBufferedInputStreamBufferedReader

InputStream - Поток байтов

Абстрактный класс для чтения последовательности байтов. Работает с сырыми бинарными данными.

Основные методы:

public abstract int read() throws IOException
  // Читает один байт (0-255), возвращает -1 при EOF

public int read(byte[] b) throws IOException
  // Читает до b.length байт в массив
  // Возвращает количество прочитанных байт

public long skip(long n) throws IOException
  // Пропускает n байт

public void close() throws IOException
  // Закрывает поток

Пример InputStream:

// Чтение файла как байты
try (InputStream is = new FileInputStream("data.bin")) {
    int byte1 = is.read();  // Читает 1 байт: 0-255
    System.out.println(byte1);  // Выведет число 65-90 для букв
    
    byte[] buffer = new byte[1024];
    int bytesRead = is.read(buffer);
    // buffer содержит прочитанные байты
}

// Типичная иерархия
InputStream is = new FileInputStream("file.txt");
InputStream buffered = new BufferedInputStream(is);  // Буферизация
InputStream data = new DataInputStream(buffered);     // Типизированное чтение

Когда использовать InputStream:

  1. Бинарные файлы: изображения, архивы, exe
  2. Потоки сети: TCP/UDP
  3. Специальные форматы: видео, аудио
  4. Когда нужны сырые байты: для кодирования/декодирования

Reader - Поток символов

Абстрактный класс для чтения последовательности символов. Работает с текстом с учётом кодировки.

Основные методы:

public int read() throws IOException
  // Читает один символ (Unicode 0-65535), возвращает -1 при EOF

public int read(char[] cbuf) throws IOException
  // Читает до cbuf.length символов в массив

public long skip(long n) throws IOException
  // Пропускает n символов

public void close() throws IOException
  // Закрывает поток

Пример Reader:

// Чтение текстового файла
try (Reader reader = new FileReader("text.txt", StandardCharsets.UTF_8)) {
    int char1 = reader.read();  // Читает 1 символ
    System.out.println((char) char1);  // Выведет символ 'A'
    
    char[] buffer = new char[1024];
    int charsRead = reader.read(buffer);
    // buffer содержит прочитанные символы
    System.out.println(new String(buffer, 0, charsRead));
}

// Типичная иерархия
Reader reader = new FileReader("file.txt");
Reader buffered = new BufferedReader(reader);  // Буферизация

Когда использовать Reader:

  1. Текстовые файлы: txt, json, xml, csv
  2. Строки: когда работаешь с символами
  3. Разные кодировки: UTF-8, UTF-16, CP1251
  4. Когда нужны символы: обработка текста

Ключевые различия

1. Единица данных

// InputStream - читает БАЙТЫ
InputStream is = new FileInputStream("file.txt");
int byte_value = is.read();  // 0-255
// Для текста нужно преобразовать в символ
char ch = (char) byte_value;  // Может быть неправильно для UTF-8!

// Reader - читает СИМВОЛЫ
Reader reader = new FileReader("file.txt");
int char_code = reader.read();  // 0-65535
char ch = (char) char_code;  // Правильный символ

2. Кодировка

// InputStream не знает о кодировке
InputStream is = new FileInputStream("file.txt");
byte[] buffer = new byte[1024];
is.read(buffer);
// Нужно вручную декодировать
String text = new String(buffer, StandardCharsets.UTF_8);

// Reader автоматически обрабатывает кодировку
Reader reader = new FileReader("file.txt", StandardCharsets.UTF_8);
char[] buffer = new char[1024];
reader.read(buffer);
String text = new String(buffer);  // Уже правильно декодировано

3. Буферизованное чтение

// InputStream
try (InputStream is = new FileInputStream("file.txt");
     BufferedInputStream bis = new BufferedInputStream(is)) {
    int b = bis.read();
}

// Reader
try (Reader reader = new FileReader("file.txt");
     BufferedReader br = new BufferedReader(reader)) {
    int ch = br.read();
    String line = br.readLine();  // Удобный метод для строк!
}

Практический пример: конвертация InputStream в Reader

// Способ 1: использовать InputStreamReader (адаптер)
InputStream is = new FileInputStream("file.txt");
Reader reader = new InputStreamReader(is, StandardCharsets.UTF_8);
// Теперь можем использовать Reader

// Способ 2: прямое использование Reader
Reader reader = new FileReader("file.txt", StandardCharsets.UTF_8);

// Способ 3: с буферизацией
Reader reader = new BufferedReader(
    new InputStreamReader(
        new FileInputStream("file.txt"),
        StandardCharsets.UTF_8
    )
);

Иерархия классов

InputStream (абстрактный)
├── FileInputStream
├── ByteArrayInputStream
├── BufferedInputStream
├── DataInputStream
└── ...

Reader (абстрактный)
├── FileReader
├── InputStreamReader (адаптер!)
├── BufferedReader
├── StringReader
└── ...

Итоговое резюме

Используй InputStream когда:

  • Работаешь с бинарными данными
  • Нужны сырые байты
  • Работаешь с потоками сети (Socket, HTTP)

Используй Reader когда:

  • Работаешь с текстовыми файлами
  • Нужно обработать кодировку
  • Работаешь с символами и строками
  • Используешь BufferedReader.readLine()

Основное правило: Reader = InputStream + Character Encoding

В чем разница между InputStream и Reader? | PrepBro