Ответ
Буферизированные потоки (BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter) добавляют к базовым потокам буфер в памяти, что значительно повышает производительность операций ввода-вывода.
Основная проблема, которую они решают: Прямое чтение/запись каждого байта (символа) — это дорогой системный вызов. Буферизация позволяет работать с данными блоками.
Преимущества:
- Снижение количества системных вызовов. Вместо тысячи обращений к диску для чтения 1000 байт, буфер (например, 8 КБ) заполняется за один вызов, и дальнейшее чтение происходит из памяти.
- Повышение производительности. Особенно заметно при работе с файлами, сетью или другими "медленными" источниками данных.
Пример чтения файла с буферизацией:
try (FileInputStream fis = new FileInputStream("large_file.dat");
BufferedInputStream bis = new BufferedInputStream(fis, 16384)) { // Буфер 16 КБ
byte[] buffer = new byte[1024];
int bytesRead;
// read() теперь считывает данные из внутреннего буфера, а не с диска
while ((bytesRead = bis.read(buffer)) != -1) {
processData(buffer, bytesRead);
}
} // Потоки закроются автоматически (try-with-resources)
По умолчанию размер буфера составляет 8 КБ (8192 байта), но его можно задать явно в конструкторе.
Важно: Буферизированные потоки — это декораторы. Они оборачивают другой поток (InputStream/OutputStream) и добавляют к нему функциональность буферизации.