In Java, ho notato che a volte le dichiarazioni System.err
vengono stampate prima delle istruzioni System.out
, anche se quest'ultimo appare prima del primo nel mio codice. Perché? Sono curioso.Perché a volte le dichiarazioni System.err vengono stampate prima?
risposta
In genere, System.out
è un flusso di output bufferizzato, pertanto il testo viene accumulato prima di essere scaricato nella posizione di destinazione. Ciò può migliorare notevolmente le prestazioni nelle applicazioni che stampano grandi quantità di testo, poiché riduce al minimo il numero di costose chiamate di sistema che devono essere effettuate. Tuttavia, ciò significa che il testo non viene sempre visualizzato immediatamente e può essere stampato molto più tardi rispetto a quando è stato scritto.
System.err
, d'altra parte, in genere non viene memorizzato nel buffer perché i messaggi di errore devono essere stampati immediatamente. Questo è più lento, ma l'intuizione è che i messaggi di errore possono essere time-critical e quindi il rallentamento del programma può essere giustificato. Secondo the Javadoc for System.err
:
In genere questo flusso corrisponde all'output di visualizzazione o un'altra destinazione di uscita specificata dall'ambiente o dall'utente host. Per convenzione, questo flusso di output viene utilizzato per visualizzare messaggi di errore o altre informazioni che dovrebbero venire all'attenzione immediata di un utente anche se il flusso di output principale, il valore della variabile out, è stato reindirizzato a un file o altra destinazione in genere non viene monitorato continuamente.
(corsivo mio)
Tuttavia, come risultato, i vecchi dati inviati a System.out
potrebbe presentarsi dopo recenti System.err
messaggi, dal momento che i dati vecchio buffer si svuota più tardi il messaggio è stato inviato a System.err
. Ad esempio questa sequenza di eventi:
- "Ciao", è tamponata ad
System.out
- "panico" viene inviato direttamente al
System.err
ed è stampato immediatamente. - "mondo!" è tamponata ad
System.out
, ei dati tamponata è stampato
comporterebbe l'uscita
PANIC
Hello, world!
Anche se Hello
stato stampato a System.out
prima PANIC
stato stampato a System.err
.
Spero che questo aiuti!
Solo per curiosità: java ha le stesse garanzie di C wrt stdout quando è collegato a un terminale? Cioè scarichiamo il buffer ogni volta che viene scritta una nuova riga? – Voo
@ Voo- Ho appena guardato il Javadoc e non sembra esserci nulla di simile. – templatetypedef
'PrintStream' è implementato per svuotare dopo quasi tutto (penso che si possa' scrivere' direttamente e non lo sia). –
Ha a che fare con il buffering e la priorità. Presumibilmente, Java (come C e C-derivati) non bufferizza System.err
, stderr
, ecc., A differenza di System.out
, stdout
, ecc. In questo modo, il sistema può garantire che molto probabilmente riceverai messaggi di errore rilevanti, anche se deve abbandonare l'output standard per una ragione o l'altra.
Da Wikipedia:
È accettabile e normale per l'output standard e l'errore standard per essere indirizzati alla stessa destinazione, ad esempio il terminale testuale.I messaggi appaiono nello stesso ordine in cui il programma li scrive, a meno che non sia coinvolto il buffering. (Ad esempio, una situazione comune si verifica quando il flusso di errore standard non viene bufferizzato, ma il flusso di output standard è bufferizzato in linea, in questo caso il testo scritto in errore standard può essere visualizzato in precedenza sul terminale, se il buffer del flusso di output standard non è ancora pieno)
Non ho mai avuto il cuore di alcuna priorità per i flussi .. come funzionava? Vorrei andare con la semplice spiegazione di buffering. – Voo
Solo un problema di lingua fiorita. Risolto per essere più tecnico :) –
A partire da 1.02 Ho bloccato con 'System.err' quando sto eseguendo degli hacker esattamente per questo motivo. Non ho idea di come si comportano le versioni più recenti di Java, perché non lo faccio testare. –