← Назад к вопросам
Происходит ли чтение текстового файла при создании 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 байта в памяти за раз
Почему это важно
Ленивое поведение дает преимущества:
- Экономия памяти — большие файлы не загружаются целиком
- Производительность — быстрое создание потока без задержек
- Потоковая обработка — можно обработать данные по частям
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, обеспечивающий эффективную работу с файлами любого размера.