2012-02-05 14 views
10

En Java, noté que a veces, las declaraciones System.err se imprimen primero antes de las declaraciones System.out, aunque esta última aparece antes que la anterior en mi código. ¿Por qué? Soy curioso.¿Por qué las sentencias System.err se imprimen primero a veces?

+0

De 1.02 Me he quedado con el uso de 'System.err' cuando estoy hackeando por exactamente esta razón. No tengo idea de cómo se comportan las versiones más recientes de Java, porque no lo pruebo. –

Respuesta

17

Normalmente, System.out es un flujo de salida en búfer, por lo que el texto se acumula antes de que se vacíe a la ubicación de destino. Esto puede mejorar drásticamente el rendimiento en aplicaciones que imprimen grandes cantidades de texto, ya que minimiza la cantidad de costosas llamadas al sistema que deben realizarse. Sin embargo, significa que el texto no siempre se muestra de inmediato, y puede imprimirse mucho más tarde de lo que fue escrito.

System.err, por otro lado, normalmente no está almacenado en el búfer porque los mensajes de error deben imprimirse inmediatamente. Esto es más lento, pero la intuición es que los mensajes de error pueden ser críticos para el tiempo, por lo que la ralentización del programa puede estar justificada. De acuerdo con the Javadoc for System.err:

Normalmente, esta corriente corresponde a la salida de visualización u otro destino de salida especificado por el entorno o usuario del host. Por convención, esta secuencia de salida se usa para mostrar mensajes de error u otra información que debe llamar la atención inmediata del usuario, incluso si el flujo de salida principal, el valor de la variable, ha sido redirigido a un archivo u otro destino eso típicamente no es monitoreado continuamente.

(el subrayado es mío)

Sin embargo, como resultado, los datos antiguos enviados a System.out podría aparecer después de System.err nuevos mensajes, ya que los datos tamponada de edad se vacía más tarde que el mensaje fue enviado a System.err. Por ejemplo, esta secuencia de eventos:

  • "Hola" está tamponada a System.out
  • "pánico" se envía directamente a System.err y se imprime inmediatamente.
  • "¡mundo!" se almacenan temporalmente para System.out, y los datos se imprime tamponada

daría lugar a la salida de

PANIC 
Hello, world! 

Aunque Hello se imprimió a System.out antes PANIC se imprimió a System.err.

Espero que esto ayude!

+0

Sólo por curiosidad: ¿Java ofrece las mismas garantías que C wrt stdout cuando se conecta a una terminal? Es decir. limpiamos el buffer cada vez que se escribe una nueva línea? – Voo

+0

@ Voo- Acabo de ver el Javadoc y no parece haber nada de este tipo. – templatetypedef

+0

'PrintStream' se implementa para enjuagar casi todo (creo que se puede' escribir' directamente y no). –

2

Tiene que ver con el almacenamiento en búfer y la prioridad. Es de suponer que Java (como C y C-derivados) no almacena en el buffer System.err, stderr, etc., a diferencia de System.out, , etc. De esta manera, el sistema puede garantizar que usted recibirá cualquier mensaje de error relevante, incluso si tiene que soltar la salida estándar por una razón u otra.

De Wikipedia:

Es aceptable-y normal-para la salida estándar y el error estándar para ser dirigidas hacia el mismo destino, tal como el terminal de texto.Los mensajes aparecen en el mismo orden en que el programa los escribe, a menos que se trate de un almacenamiento en búfer. (Por ejemplo, una situación común es cuando el flujo de error estándar está sin búfer pero el flujo de salida estándar está en búfer de línea, en este caso, el texto escrito en error estándar más tarde puede aparecer en el terminal antes, si el búfer del flujo de salida estándar no aún lleno.)

+0

Nunca tuve corazón de ninguna prioridad para las transmisiones ... ¿Cómo funcionó eso? Me gustaría ir con la simple explicación de almacenamiento en búfer. – Voo

+0

Simplemente un problema de lenguaje floral. Corregido para ser más técnico :) –

Cuestiones relacionadas