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?
Respuesta
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!
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
@ Voo- Acabo de ver el Javadoc y no parece haber nada de este tipo. – templatetypedef
'PrintStream' se implementa para enjuagar casi todo (creo que se puede' escribir' directamente y no). –
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.)
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
Simplemente un problema de lenguaje floral. Corregido para ser más técnico :) –
- 1. Las constantes entre comillas no se imprimen?
- 2. ¿Por qué mis hash se imprimen como cadenas?
- 3. ¿Cómo se imprimen iframes?
- 4. ¿Por qué JAXB a veces se asigna a JAXBElement?
- 5. ¿Por qué __init__ no se llama después __new__ A VECES
- 6. ¿Por qué $ Id $ a veces no se expande en SVN?
- 7. ¿Por qué WebBrowser_DocumentCompleted() se activa dos veces?
- 8. ¿Por qué EAAccessoryDidConnectNotification se produce dos veces?
- 9. ¿Por qué contextInitialized() se llama varias veces?
- 10. Python: ¿Por qué os.getcwd() a veces se bloquea con OSError?
- 11. ¿Por qué swap() a veces se implementa pasando una matriz?
- 12. Desactivar System.err
- 13. ¿Por qué onKey() se llama dos veces?
- 14. ¿Por qué MATLAB se ralentiza cuando se imprimen muchas figuras (.png)?
- 15. ¿Por qué las excepciones de python normalmente no imprimen valores ofensivos?
- 16. ¿Por qué las variables de condición a veces se activan erróneamente?
- 17. ¿Por qué las animaciones de la vista a veces se recortan?
- 18. ¿Por qué los métodos C++ a veces se definen dentro de las clases?
- 19. ¿Por qué los objetos R no se imprimen en una función o en un bucle "for"?
- 20. ¿A dónde deberían ir las sentencias 'CreateMap'?
- 21. ¿Cómo se imprimen los archivos XPS?
- 22. ¿Por qué las consultas WMI son tan lentas algunas veces?
- 23. ¿Por qué popViewController sólo funcionan todas las otras veces
- 24. Redirigir System.out y System.err a slf4j
- 25. ¿Por qué las selecciones JList ocurren dos veces?
- 26. Wordpress: ¿por qué se invoca el hook init varias veces?
- 27. ¿Por qué ServiceModel a veces se declara en Web.config de la carpeta Framework y, a veces, no?
- 28. ¿Por qué las variables no son locales en las sentencias de caso?
- 29. ¿Por qué numberOfSectionsInTableView se llama dos veces en UITableViewController?
- 30. ¿por qué Hibernate selecciona las mismas columnas dos veces?
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. –