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

Происходит ли чтение текстового файла при создании InputStream

2.0 Middle🔥 121 комментариев
#Docker, Kubernetes и DevOps#JVM и управление памятью#ORM и Hibernate

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

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

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

Происходит ли чтение текстового файла при создании InputStream

Это отличный вопрос, который проверяет понимание ленивых вычислений и моментов инициализации в Java. Ответ: НЕТ, файл не читается при создании InputStream — чтение происходит только при вызове методов чтения.

Основной принцип: Ленивое чтение (Lazy Reading)

InputStream inputStream = new FileInputStream("file.txt");
// В этот момент:
// ✓ Файл открывается (дескриптор файла)
// ✗ Содержимое файла НЕ читается в память
// ✗ Данные НЕ буферизируются

System.out.println("InputStream создан");

byte[] buffer = new byte[1024];
int bytesRead = inputStream.read(buffer);
// ЗДЕСЬ происходит чтение!

inputStream.close();

Демонстрация с логированием

public class FileReadingDemo {
    public static void main(String[] args) throws IOException {
        System.out.println("1. До создания InputStream");
        
        FileInputStream fis = new FileInputStream("large_file.txt");
        System.out.println("2. InputStream создан (файл открыт, но не прочитан)");
        
        byte[] buffer = new byte[10];
        int read = fis.read(buffer);
        System.out.println("3. Прочитано " + read + " байт");
        
        fis.close();
        System.out.println("4. Поток закрыт");
    }
}

Различие между разными типами InputStream

1. FileInputStream — ленивое чтение

FileInputStream fis = new FileInputStream("file.txt");
// Только открытие файла, без чтения
byte[] data = fis.readAllBytes();  // Вот здесь читается все
fis.close();

2. ByteArrayInputStream — данные в памяти

byte[] data = "Hello".getBytes();
ByteArrayInputStream bais = new ByteArrayInputStream(data);
// Данные уже в памяти (в конструкторе)

3. BufferedInputStream — с буферизацией

FileInputStream fis = new FileInputStream("file.txt");
BufferedInputStream bis = new BufferedInputStream(fis, 8192);
// Даже при создании BufferedInputStream данные не читаются
byte[] buffer = new byte[100];
bis.read(buffer);  // ЗДЕСЬ происходит чтение из файла в буфер
bis.close();

Что происходит при создании FileInputStream

FileInputStream fis = new FileInputStream("myfile.txt");

// На низком уровне:
// 1. JVM вызывает системный вызов open() (ОС уровень)
// 2. Получает дескриптор файла (file descriptor)
// 3. Сохраняет дескриптор в объекте InputStream
// 4. Возвращает управление программе

// НО:
// ✗ Не читается ни один байт из файла
// ✗ Не буферизируется содержимое
// ✗ Не занимается memoria для содержимого файла

Практический пример: Большой файл

File largeFile = new File("1GB_file.txt");
System.out.println("Размер файла: " + largeFile.length() + " bytes");

long before = Runtime.getRuntime().totalMemory();
InputStream is = new FileInputStream(largeFile);
long after = Runtime.getRuntime().totalMemory();

System.out.println("Память до: " + before);
System.out.println("Память после: " + after);
System.out.println("Прирост: " + (after - before) + " bytes");
// Результат: минимальный прирост (несколько КБ)

byte[] buffer = new byte[8192];
int bytesRead = is.read(buffer);
// Только 8192 байта в памяти за раз

Почему это важно

Ленивое поведение дает преимущества:

  1. Экономия памяти — большие файлы не загружаются целиком
  2. Производительность — быстрое создание потока без задержек
  3. Потоковая обработка — можно обработать данные по частям
try (FileInputStream fis = new FileInputStream("huge_file.txt")) {
    byte[] buffer = new byte[8192];
    int bytesRead;
    
    while ((bytesRead = fis.read(buffer)) != -1) {
        processData(buffer, bytesRead);
        // Память используется только для одного чанка
    }
}

Сравнение: Ленивое vs Немедленное чтение

// Ленивое (потоковое)
InputStream is = new FileInputStream("file.txt");
// Только открытие
is.read();
// Чтение происходит здесь

// Немедленное (в память)
byte[] data = Files.readAllBytes(Paths.get("file.txt"));
// Весь файл загружен в памяти

Когда происходит реальное чтение

FileInputStream fis = new FileInputStream("file.txt");
// ↑ Создание InputStream - НО ЧТЕНИЯ НЕТ

// ✓ Реальное чтение происходит в этих методах:
fis.read();           // Читает 1 байт
fis.read(buffer);     // Читает в буфер
fis.readAllBytes();   // Читает все
fis.readNBytes(n);    // Читает n байт
fis.skip(n);          // Пропускает n байт

Вывод

Создание InputStream — это быстрая операция, которая не вызывает чтение файла. Реальное чтение ленивое и происходит только при явном вызове методов чтения. Это фундаментальный дизайн Java IO, обеспечивающий эффективную работу с файлами любого размера.

Происходит ли чтение текстового файла при создании InputStream | PrepBro