Когда/почему вызывать System.out.flush() в Java
Почему некоторые потоки необходимо очищать (FileOutputStream
и потоки из сокетов), в то время как стандартный выходной поток не работает?
Каждый раз, когда кто-то использует объект System.out
PrintStream
, будь он при вызове println()
или write()
, они никогда не очищают поток. Однако другие программисты обычно называют flush()
a PrintStream
/PrintWriter
другими потоками.
Я недавно задал этот вопрос нескольким программистам, а некоторые считают, что в Java есть некоторая обработка фонового изображения, чтобы автоматически очистить поток System.out
, но я не могу найти документацию по этому вопросу.
Что-то вроде этого заставляет меня задаться вопросом, является ли просто вызов System.out.println()
независимым от платформы, поскольку некоторые системы могут понадобиться вам для очистки потока.
Ответы
Ответ 1
System.out
основан на PrintStream
, который по умолчанию сбрасывается всякий раз, когда записывается новая строка.
Из javadoc:
autoFlush - логическое; если true, выходной буфер будет сбрасываться всякий раз, когда записывается массив байтов, вызывается один из методов println
или записывается символ новой строки или байта ('\n'
)
Таким образом, описанный вами случай println
явно обрабатывается, а случай write
с byte[]
также гарантированно очищается, потому что он подпадает под "всякий раз, когда байт-массив написан".
Если вы замените System.out
на System.setOut
и не будете использовать поток автозаполнения, тогда вам нужно будет очистить его, как и любой другой поток.
Библиотечный код, вероятно, не должен использовать System.out
напрямую, но если это так, то он должен быть осторожным, потому что пользователь библиотеки может переопределить System.out
, чтобы использовать поток без очистки.
Любая программа Java, которая записывает двоичный вывод в System.out
, должна быть осторожна до flush
до exit
, потому что двоичный вывод часто не включает завершающую новую строку.
Ответ 2
Из PrintStream
документации:
Необязательно, a PrintStream
может быть создан для автоматической смены; это означает, что метод flush
автоматически вызывается после записи байтового массива, вызывается один из методов println
или записывается символ новой строки или байта ('\n'
).
Хотя я не вижу в нем явно упоминания, я понимаю, что System.out
выполнит эту автоматическую промывку.
Ответ 3
Если вы не можете дождаться появления элемента, сбросьте поток.
Когда JVM идет вниз, а не очистка потока, он рискует потерять элемент в буфере дисплея, что может сделать разумное сообщение об ошибке, сообщающее вам, почему JVM потерял навсегда. Это делает отладку гораздо более сложной, как люди тогда склонны говорить: "но она не попала сюда, потому что она напечатала бы это".
Ответ 4
System.out по умолчанию буферизируется по строке. Поэтому, если вы вызываете println
, а не print
, это не должно быть проблемой. Подробнее см. в этой статье.