Карта / I/O и файлы / InputStream / OutputStream

InputStream / OutputStream

I/O (Input/Output) — чтение и запись данных: файлы, сеть, память. Java работает с данными через потоки (streams) — не путать со Stream API! Здесь поток — это непрерывная последовательность байт, которую можно читать или писать.

Два направления:

  • InputStream — читаем откуда-то (файл, сеть, память)
  • OutputStream — пишем куда-то (файл, сеть, память)
// Читаем файл байт за байтом
try (InputStream in = new FileInputStream("data.bin")) {
    int b;
    while ((b = in.read()) != -1) {  // -1 = конец файла
        System.out.print(b);
    }
}

// Пишем байты в файл
try (OutputStream out = new FileOutputStream("result.bin")) {
    out.write(new byte[]{72, 101, 108, 108, 111}); // "Hello" в байтах
}

try-with-resources закрывает поток автоматически — так и нужно всегда делать, иначе файл останется заблокированным.

Буферизация — читать по одному байту медленно (каждый вызов read() = системный вызов). BufferedInputStream читает сразу блоками в память:

try (InputStream in = new BufferedInputStream(new FileInputStream("big.bin"))) {
    // теперь читает по 8KB за раз — в разы быстрее
}
Копнуть глубже

Паттерн Decorator в I/O. Потоки в Java устроены как матрёшки — один оборачивает другой, добавляя функциональность. Это и есть паттерн Decorator:

new DataOutputStream(           // умеет писать int, double, String
  new BufferedOutputStream(     // буферизует
    new FileOutputStream("f"))) // пишет в файл

Каждый слой добавляет одну ответственность, не меняя интерфейс — любой OutputStream можно обернуть в любой другой.

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

InputStream FileInputStream ByteArrayInputStream BufferedInputStream DataInputStream OutputStream FileOutputStream ByteArrayOutputStream BufferedOutputStream DataOutputStream

ByteArrayOutputStream полезен когда нужно собрать байты в памяти, а не в файл — например, сериализовать объект и отправить по сети:

ByteArrayOutputStream buf = new ByteArrayOutputStream();
// ... пишем в buf ...
byte[] bytes = buf.toByteArray(); // забираем результат
🎤 Закрыл тему, если можешь объяснить:
• разницу InputStream и OutputStream, зачем try-with-resources;
• что такое буферизация и паттерн Decorator в контексте I/O (если дошёл до 2-го слоя).