Почему операторы System.err иногда печатаются первыми?
В Java я заметил, что иногда System.err
заявления печатаются в первую очередь, прежде чем System.out
заявления, хотя последний появляется первым перед первым в моем коде. Зачем? Мне любопытно.
2 ответа
Как правило, System.out
является буферизованным выходным потоком, поэтому текст накапливается до того, как он будет сброшен в место назначения. Это может значительно повысить производительность в приложениях, которые печатают большие объемы текста, поскольку минимизирует количество дорогостоящих системных вызовов, которые необходимо выполнить. Однако это означает, что текст не всегда отображается сразу и может быть распечатан намного позже, чем он был написан.
System.err
с другой стороны, обычно не буферизируется, потому что сообщения об ошибках должны быть напечатаны немедленно. Это медленнее, но интуиция заключается в том, что сообщения об ошибках могут быть критичны по времени, и поэтому замедление работы программы может быть оправдано. Согласно Javadoc дляSystem.err
:
Обычно этот поток соответствует выводу на экран или другому назначению вывода, указанному хост-средой или пользователем. По соглашению этот выходной поток используется для отображения сообщений об ошибках или другой информации, которая должна быть незамедлительно предоставлена пользователю, даже если основной выходной поток, значение переменной out, было перенаправлено в файл или другое место назначения, которое как правило, не контролируется непрерывно.
(Мой акцент)
Однако в результате старые данные отправляются на System.out
может появиться после нового System.err
сообщения, поскольку старые буферизованные данные сбрасываются позже, чем сообщение было отправлено System.err
, Например, эта последовательность событий:
- "Привет" буферизируется в
System.out
- "ПАНИКА" отправляется напрямую
System.err
и распечатывается сразу. - " Мир!" буферизируется в
System.out
и буферизованные данные напечатаны
Приведет к выводу
PANIC
Hello, world!
Даже если Hello
был напечатан в System.out
до PANIC
был напечатан в System.err
,
Надеюсь это поможет!
Это связано с буферизацией и приоритетом. Предположительно, Java (как C и C-производные) не буферизует System.err
, stderr
и т. д., в отличие от System.out
, stdout
и т. д. Таким образом, система может гарантировать, что вы, скорее всего, получите любые соответствующие сообщения об ошибках, даже если по той или иной причине ей придется отбросить стандартный вывод.
Из Википедии:
Приемлемо - и это нормально - стандартный вывод и стандартная ошибка направляются в одно и то же место, например, к текстовому терминалу. Сообщения появляются в том же порядке, в котором их записывает программа, если не используется буферизация. (Например, обычная ситуация, когда стандартный поток ошибок не буферизован, но стандартный поток вывода буферизован строкой; в этом случае текст, записанный в стандартную ошибку позже, может появиться на терминале раньше, если буфер стандартного потока вывода не еще не полный.)