2011-08-23 104 views
43

¿Por qué ciertas corrientes se deben purgar (FileOutputStream y las transmisiones desde Sockets) mientras que la secuencia de salida estándar no?Cuándo/por qué llamar a System.out.flush() en Java

Cada vez que alguien utiliza el objeto System.outPrintStream, ya sea durante una llamada o println()write(), nunca se vacía el stream. Sin embargo, otros programadores suelen llamar al flush() a PrintStream/PrintWriter con otras transmisiones.

Hace poco hice esta pregunta a varios programadores y algunos creen que hay algo de manejo de fondo en Java para auto-enjuagar el flujo System.out, pero no puedo encontrar ninguna documentación sobre eso.

Algo como esto me hace preguntarme si simplemente llamar a System.out.println() es independiente de la plataforma, ya que algunos sistemas pueden necesitar que purgue la corriente.

Respuesta

43

System.out se basa en un PrintStream que por defecto se vacía cada vez que se escribe una nueva línea.

Desde el javadoc:

autoFlush - Un booleano; si es cierto, el búfer de salida se vaciará cada vez que un conjunto de bytes se escribe, uno de los métodos println se invoca, o un carácter de nueva línea o byte ('\n') se escribe

Así el caso println mencionas se maneja de forma explícita , y la caja write con un byte[] también está garantizada al ras porque cae bajo "siempre que se escribe un conjunto de bytes".

Si reemplaza System.out utilizando System.setOut y no utiliza un flujo de autoflushing, tendrá que enjuagarlo como cualquier otra corriente.

El código de la biblioteca probablemente no debería estar usando System.out directamente, pero si lo hace, debe tener cuidado de enjuagar porque un usuario de la biblioteca puede anular System.out para usar una corriente que no se descarga.

Cualquier programa Java que escriba la salida binaria a System.out debe tener cuidado con flush antes de exit porque la salida binaria a menudo no incluye una nueva línea final.

+3

solo válido 'si es verdadero', pero ¿verdad? No pude encontrar ninguna documentación sobre el valor de autoFlush para System.out ... –

+1

@Carlos, depende del sistema que arranque la JVM y lance la clase principal con lo que 'System.out' y' System.err' son obligado y cómo se tiñen. Cuando utiliza el binario 'java' para iniciar una clase' System.out' se inicializa a algo así como 'new PrintStream (nuevo FileOutputStream (FileDescriptor.out), true, System.getProperty (" file.encoding "))' pero otro JVMs difieren. Obviamente, una JVM que inserta applets hace algo diferente. –

+0

@MikeSamuel, ¿Significa que todavía * necesitamos * para enjuagar de todos modos, ya que el comportamiento del autoenjuague no está ** garantizado ** por las especificaciones? – Pacerier

2

System.out es por defecto buffer de línea. Entonces, si llama al println y no al print, no debería ser un problema. Ver this article para más información.

+1

Lo sentimos, println no tiene que ser utilizado para obtener autoflush para PrintStream. Por favor verificar. –

5

Desde el PrintStream documentation:

Opcionalmente, un PrintStream se pueden crear con el fin de eliminar de forma automática; esto significa que el método flush se invoca automáticamente después de escribir una matriz de bytes, se invoca uno de los métodos println o se escribe un carácter o byte de nueva línea ('\n').

Aunque no lo veo explícitamente en la documentación, entiendo que System.out realizará esta limpieza automática.

3

Cuando no puede esperar a que se muestre el artículo, enjuague la corriente.

Cuando la JVM se cae, el flujo de la corriente no corre el riesgo de perder el elemento en el búfer de visualización, lo que puede hacer que el mensaje de error le indique por qué la JVM se perdió para siempre. Eso hace que la depuración sea mucho más difícil, ya que la gente tiende a decir, "pero no llegó hasta aquí, porque habría impreso esto".