Какие потоки в Java IO оснащены внутренним буфером?

Добрый день! 

В некоторых источниках утверждается, что потоки OutputStream и Writer, а также их подклассы имеют внутренний буфер и автоматически буферизуются, в то время как InputStream и Reader и их производные - нет. К тому же, они реализуют интерфейс Flushable. Однако в документации указано, что, например, PipedInputStream и FileReader обладают внутренним буфером и автоматически буферизуются, но при этом не реализуют интерфейс Flushable. 

Как можно однозначно определить, какие потоки содержат внутренний буфер и автоматически буферизуются, а какие нет? Получается, что некоторые классы, не реализующие интерфейс Flushable, все равно могут иметь внутренний буфер и буферизоваться, что ставит под сомнение значимость этого интерфейса как критерия?
  • 27 февраля 2025 г. 20:34
Ответы на вопрос 2
Добрый день!

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

### Буферизация в потоках

1. **Потоки с внутренним буфером**:
   - **OutputStream** и **Writer**, а также их подклассы: многие из них реализуют буферизацию для оптимизации записи данных. Примеры:
     - `BufferedOutputStream`
     - `BufferedWriter`
   - Эти классы могут использовать внутренний буфер для группирования записей перед их фактической отправкой в целевой поток.

2. **Потоки без внутреннего буфера**:
   - **InputStream** и **Reader** не имеют встроенной буферизации по умолчанию, но это зависит от конкретных подклассов:
     - Например, `FileReader` может не иметь собственного буфера, в то время как `BufferedReader` использует буфер для чтения данных.
   - Однако некоторые потоки, такие как `PipedInputStream`, могут использовать буфер, хотя и не реализуют интерфейс **Flushable**.

### Интерфейс Flushable

Интерфейс **Flushable** предназначен для того, чтобы обеспечить возможность сброса данных из буфера в целевое устройство. Это в основном актуально для потоков вывода, которые могут иметь буфер.

### Как определить наличие буфера?

- **Документация**: Наиболее надежным способом является изучение официальной документации Java для каждого конкретного класса. В ней обычно указывается, реализует ли класс буферизацию.
  
- **Общие категории**:
  - **Классы, которые обязательно имеют буфер**: `BufferedOutputStream`, `BufferedWriter`, `BufferedReader`, `BufferedInputStream`.
  - **Классы, которые не имеют буфер**: такие как `FileOutputStream`, `FileInputStream`, `Writer` и `OutputStream` в базовом виде.

### Заключение

Вы правы, что наличие интерфейса **Flushable** не всегда является надежным индикатором наличия внутреннего буфера. Чтобы однозначно понимать, какие потоки имеют внутренний буфер, необходимо изучать документацию к каждому конкретному классу или полагаться на общепринятые рекомендации о классах, которые уже были исследованы и протестированы.
Ты задаешь вопросы в основном по абстрактным классам. А в них обычно нет ничего интересного. 
И размер буфера это как раз особенности реализации в наследнике.

Для буферизации InputStream можно использовать такую обертку.

BufferedInputStream strm = new BufferedInputStream(new FileInputStream("file"), 128 * 1024);
Похожие вопросы