Почему в PrintWriter функция print() также не выполняет автоматическую очистку?
При взгляде на PrintWriter
договор на следующий конструктор:
public PrintWriter(OutputStream out, boolean autoFlush)
Создает новый
PrintWriter
из существующегоOutputStream
, Этот удобный конструктор создает необходимые промежуточныеOutputStreamWriter
, который преобразует символы в байты, используя кодировку символов по умолчанию.Параметры:
out
- выходной потокautoFlush
- Аboolean
; еслиtrue
,println
,printf
, или жеformat
методы очистят буфер выводаСмотрите также: OutputStreamWriter.OutputStreamWriter(java.io.OutputStream)
Обратите внимание на autoFlush
флаг работает только на println
, printf
, а также format
, Теперь я знаю, что printf
а также format
в основном делают то же самое, что и print
кроме как с большим количеством опций, но я просто не понимаю, почему они не включают print
а также в договоре. Почему они приняли это решение?
1 ответ
Я подозреваю, что это потому, что авторы Java делают предположения о производительности:
Рассмотрим следующий код:
public static void printArray(int[] array, PrintWriter writer) {
for(int i = 0; i < array.length; i++) {
writer.print(array[i]);
if(i != array.length - 1) writer.print(',');
}
}
Вы почти наверняка не захотите вызывать такой метод flush()
после каждого звонка. Это может сильно повлиять на производительность, особенно для больших массивов. И, если по какой-то причине вы этого хотите, вы можете просто позвонить flush
себя
Идея в том, что printf
, format
, а также println
Скорее всего, методы будут печатать хороший кусок текста сразу, поэтому имеет смысл очищать после каждого. Но это редко, если вообще когда-либо, имеет смысл сбрасывать только после 1 или нескольких символов.
После некоторых поисков я нашел цитату для этого рассуждения (выделение мое):
Большинство примеров, которые мы видели до сих пор, используют небуферизованный ввод / вывод. Это означает, что каждый запрос на чтение или запись обрабатывается непосредственно базовой ОС. Это может сделать программу намного менее эффективной, поскольку каждый такой запрос часто вызывает доступ к диску, сетевую активность или какую-либо другую операцию, которая является относительно дорогой.
Чтобы уменьшить этот вид издержек, платформа Java реализует буферизованные потоки ввода / вывода. Буферизованные входные потоки считывают данные из области памяти, известной как буфер; родной API ввода вызывается только тогда, когда буфер пуст. Аналогично, буферизованные выходные потоки записывают данные в буфер, а собственный API вывода вызывается только тогда, когда буфер заполнен.
<Вырезано>
Часто имеет смысл выписывать буфер в критических точках, не дожидаясь его заполнения. Это известно как очистка буфера.
Некоторые буферизованные выходные классы поддерживают автозапуск, указанный необязательным аргументом конструктора. Когда автоматическая очистка включена, определенные ключевые события вызывают сброс буфера. Например, автозапуск
PrintWriter
объект очищает буфер при каждом вызовеprintln
или жеformat
,