2011-08-23 14 views
43

Perché alcuni flussi devono essere scaricati (FileOutputStream e flussi da Socket) mentre il flusso di output standard no?Quando/perché chiamare System.out.flush() in Java

Ogni volta che qualcuno utilizza l'oggetto System.outPrintStream, sia durante la chiamata o println()write(), non hanno mai sciacquare il torrente. Tuttavia, altri programmatori chiamano abitualmente flush() a PrintStream/PrintWriter con altri flussi.

Recentemente ho fatto questa domanda a diversi programmatori e alcuni credono che ci sia un po 'di gestione in background in Java per lo scarico automatico del flusso System.out ma non riesco a trovare alcuna documentazione al riguardo.

Qualcosa di simile mi fa meravigliare se chiamare semplicemente System.out.println() sia indipendente dalla piattaforma poiché alcuni sistemi potrebbero aver bisogno di scaricare lo stream.

risposta

43

System.out è basato su un PrintStream che per impostazione predefinita svuota ogni volta che viene scritta una nuova riga.

Dal javadoc:

autoflush - Un valore booleano; Se fosse vero, il buffer di uscita sarà lavato ogni volta che un array di byte è scritto, uno dei println metodi viene invocato, o un carattere di nuova riga o di byte ('\n') è scritto

Così il caso println si parla esplicitamente gestita e anche il caso write con uno byte[] viene svuotato perché rientra in "ogni volta che viene scritto un array di byte".

Se si sostituisce utilizzando System.setOut e non si utilizza un flusso di autoflush, sarà necessario svuotarlo come qualsiasi altro flusso.

Il codice della libreria probabilmente non dovrebbe utilizzare System.out direttamente, ma se lo fa, allora dovrebbe fare attenzione a svuotare perché un utente della libreria potrebbe sovrascrivere System.out per utilizzare un flusso non di scarico.

Qualsiasi programma Java che scrive l'output binario su System.out deve fare attenzione a flush prima dello exit perché l'output binario spesso non include una nuova riga finale.

+3

valido solo se è vero, ma è vero? Non sono riuscito a trovare alcuna documentazione sul valore di autoFlush per System.out ... –

+1

@Carlos, Spetta al sistema che avvia la JVM e lancia la classe principale quali 'System.out' e' System.err' sono legato a come arrossiscono. Quando si usa il file 'java' per avviare una classe' System.out' viene inizializzato su qualcosa come 'new PrintStream (nuovo FileOutputStream (FileDescriptor.out), vero, System.getProperty (" file.encoding "))' ma altro Le JVM differiscono. Ovviamente una JVM che incorpora le applet fa qualcosa di diverso. –

+0

@MikeSamuel, Quindi vuol dire che abbiamo * bisogno * di svuotare comunque perché il comportamento dell'autoflush non è ** garantito ** dalle specifiche? – Pacerier

2

System.out è di default con buffer di linea. Quindi se stai chiamando println e non print non dovrebbe essere un problema. Vedi this article per maggiori informazioni.

+1

Spiacente, println non deve essere utilizzato per ottenere autoflush per PrintStream. Si prega di verificare. –

5

Dal PrintStream documentation:

Facoltativamente, un PrintStream può essere creato in modo da spurgare automaticamente; ciò significa che il metodo flush viene richiamato automaticamente dopo la scrittura di una matrice di byte, viene invocato uno dei metodi o viene scritto un carattere o un byte di nuova riga ('\n').

Anche se non lo vedo menzionato esplicitamente nella documentazione, è a mia conoscenza che System.out eseguirà questo auto-lavaggio.

3

Quando non è possibile attendere la visualizzazione dell'elemento, svuotare il flusso.

Quando la JVM si interrompe, lo svuotamento del flusso rischia di perdere l'elemento nel buffer di visualizzazione, il che potrebbe far sì che il messaggio di errore ragionevole indichi perché la JVM è andata persa per sempre. Ciò rende il debug molto più difficile, in quanto le persone tendono a dire "ma non è arrivato qui, perché lo avrebbe stampato".