2012-02-05 1 views
10

В Java я заметил, что иногда операторы System.err печатаются перед операторами System.out, хотя последний появляется первым перед первым в моем коде. Зачем? Мне любопытно.Почему заявления System.err сначала печатаются?

+0

От 1.02 Я застрял с использованием 'System.err', когда я взламываю именно по этой причине. Не знаю, как ведут себя более современные версии Java, потому что я не тестирую их. –

ответ

17

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

System.err, с другой стороны, обычно не буферизуется, потому что сообщения об ошибках должны быть распечатаны немедленно. Это медленнее, но интуиция заключается в том, что сообщения об ошибках могут быть критичными по времени, и поэтому замедление программы может быть оправдано. Согласно the Javadoc for System.err:

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

(курсив мой)

Однако, в результате, старые данные, посылаемые System.out может появиться после того, как новые System.err сообщений, так как старые буферном данные сброшены позже, чем сообщение было отправлено System.err. Например, эта последовательность событий:

  • «Привет,» в буфер для System.out
  • «PANIC» отправляется непосредственно в System.err и печатается сразу.
  • "мир!" буферизуются в System.out и буферные данные распечатываются

привели бы к выходу

PANIC 
Hello, world! 

Даже если Hello было напечатан в System.out до того PANIC был напечатан в System.err.

Надеюсь, это поможет!

+0

Просто из любопытства. Является ли java теми же гарантиями, что и C wrt stdout при подключении к терминалу? То есть мы очищаем буфер каждый раз, когда записывается новая строка? – Voo

+0

@ Voo- Я просто посмотрел на Javadoc и, похоже, ничего подобного не было. – templatetypedef

+0

'PrintStream' реализован, чтобы очистить после почти всего (я думаю, что вы можете напрямую« писать », а это не так). –

2

Это связано с буферизацией и приоритетом. Предположительно, Java (например, C и C-производные) не поддерживает System.err, stderr и т. Д., В отличие от System.out, stdout и т. Д. Таким образом, система может гарантировать, что вы, скорее всего, получите соответствующие сообщения об ошибках, даже если это должен отказаться от стандартного вывода по той или иной причине.

От Wikipedia:

Это приемлемо-и нормальной для стандартного вывода и стандартной ошибки должны быть направлены в том же направлении, как, например текстовый терминал.Сообщения отображаются в том же порядке, в каком программа записывает их, если не используется буферизация. (Например, обычная ситуация заключается в том, что стандартный поток ошибок небуферизирован, но стандартный выходной поток буферизируется по строке, в этом случае текст, записанный в стандартную ошибку позже, может появляться на терминале раньше, если буфер стандартного выходного потока не является но полный.)

+0

У меня никогда не было приоритетов для потоков ... как это работает? Я бы пошел с простым объяснением буферизации. – Voo

+0

Просто проблема с цветочным языком. Исправлено, чтобы быть более техническим :) –

 Смежные вопросы

  • Нет связанных вопросов^_^