Как работает метод flush() в Java?

Подскажите пожалуйста такой момент. Не совсем понимаю как именно работает метод flush() при использовании потоков вывода. Из прочитанного я понял, что он нужен для независимого сброса буфера и записи данных. Есть специальные буферизированные потоки BufferedOutputStream и BufferedWriter для байтов и символов, где имеется внутренний буфер, чтобы не обращаться каждый раз к внешнему источнику (файлу, сетевому сокету и т.д.). Какой смысл тогда этого метода в обычных "не-буферизированных" классах, которые мгновенно записывают данные?

import java.io.*;

public class Program {
 
    public static void main(String[] args) {
        
        try(FileWriter writer = new FileWriter("note.txt")
        {
            String text = "Some text";
            writer.write(text);
            
            writer.flush();
        }
        catch(IOException ex){
             
            System.out.println(ex.getMessage());
        } 
    } 
}

Ответы (2 шт):

Автор решения: Qwertiy

метод flush()

Нужен для того, чтобы отправить данные непосредственно на диск, в сеть или куда-то ещё.

Без flush эти данные, в зависимости от потока, могут лежать в каком-то буфере и ожидать, пока он заполнится.

Какой смысл тогда этого метода в обычных "не-буферизированных" классах, которые мгновенно записывают данные?

Соответствие интерфейсу.

Коду, работающему с потоком, вовсе не обязательно знать, является ли поток буферизируемым. А если у небуферизированных потоков убрать метод flush, то получится, что это невозможно если алгоритм работы предполагает в каких-то ситуациях принудительную запись. Очевидно, что небуферизированные потоки в любой момент времени находятся в том же состоянии, как если бы перед эти был вызван метод flush, поэтому добавить им такой метод, который внутри ничего не делает - весьма элегантное решение.

PS: В приведённом примере кода flush будет бесполезен с любым потоком, поскольку при завершении блока в finally вызовется закрытие потока, которое предварительно делает flush.

→ Ссылка
Автор решения: Roman C

Из документации метода OutputStream::flush():

Очищает выходной поток и принудительно записывает все буферизованные выходные байты. Общий контракт flush заключается в том, что его вызов является указанием на то, что если какие-либо ранее записанные байты были буферизованы реализацией выходного потока, такие байты должны быть немедленно записаны в их предполагаемое место назначения.

Так, что в "не-буффиризованных" классах, данные могут быть буфферизованы.

Буферизация в основном выполняется для повышения производительности ввода-вывода.


Например, если используется FileWriter, то

Конструкторы этого класса предполагают, что кодировка символов по умолчанию и размер байт-буфера по умолчанию приемлемы. Чтобы указать эти значения самостоятельно, создайте OutputStreamWriter на FileOutputStream.

→ Ссылка