6
votes

Imprimer la sortie et un message d'erreur sur la console

J'essaye d'imprimer la sortie et un message d'erreur sur la console. mais parfois la séquence des changements de sortie, d'abord il imprime le message d'erreur et ensuite il imprime le message simple est-ce que quelqu'un peut m'aider à comprendre pourquoi cela se produit comme tel? la séquence de sortie change la plupart du temps. Il n'y a pas de cohérence dans la sortie imprimée. J'utilise eclipse IDE et la sortie que j'obtiens est la suivante.

J'ai essayé d'imprimer le code suivant,

System.out.println("simple message");  
System.err.println("error message");  

le résultat attendu est le suivant: p>

message simple

message d'erreur

mais le résultat réel est le suivant:

message d'erreur

message simple


3 commentaires

Probablement parce qu'il s'agit de deux flux différents


Copie possible de Java: System.out.println et System.err.println en panne


@ user489872 a raison - stackoverflow.com/a/1883333/4892907


7 Réponses :


3
votes

System.out.println () et System.err.println () sont des flux d'exécution différents. Les flux de sortie sont mis en cache de sorte que toute l'écriture va dans cette mémoire tampon. Après une période de calme, ils sont en fait écrits. Voici une boucle for qui montre à nouveau votre erreur:

OutErr
Out
Out
Out
Out
Out

Err
Err
Err
Err
Err

Pour "vider" les Streams, appelez .flush () à chaque fois dans la boucle:

for(int x = 0; x <= 5; x++) {
    System.out.println("Out");
    System.out.flush();
    System.err.println("Err");
    System.err.flush();


}

Dans cette boucle for, le message de sortie et le message d'erreur seront initialement imprimés, mais à chaque vidage, vos messages s'affichent en premier, puis vos messages d'erreur. La sortie sera quelque chose comme:

for(int x = 0; x <= 5; x++) {
    System.out.println("Out");
    System.err.println("Err");



}

Et c'est parce que System.out et System.err s'exécutent sur différents Streams.


0 commentaires

0
votes

Puisqu'il s'agit de deux flux d'exécution différents, ils s'exécutent indépendamment. Et ils ne sont pas non plus dans une portée de bloc différente, donc close () n'est pas appelée, ce qui empêche également d'appeler flush (). Ensuite, ils sont au même niveau. JVM prend donc les devants ici et exécute ces deux flux comme il le souhaite.

Par conséquent, appeler intentionnellement flush () à la fin de chaque flux vous aidera à revenir au siège de votre code


1 commentaires

J'ai essayé d'appeler flush () après chaque instruction, mais j'obtiens toujours la même sortie qui n'est pas la sortie souhaitée.



0
votes

essayez ceci ..

System.out.println("Out");

 System.out.flush();

 System.err.flush();

 System.err.println(" err ");


1 commentaires

non, cela n'a pas fonctionné, le message d'erreur s'imprime en premier.



0
votes

Comme suggéré dans les réponses précédentes, vous pouvez définir le même flux pour le flux de sortie et d'erreur en utilisant System.setErr

System.setErr(System.out);

Réaffecte le flux de sortie d'erreur "standard".

Mais cette configuration n'est pas recommandée pour une application réelle dans un environnement de production


0 commentaires

0
votes
  • N'oubliez pas que cela ne dépend pas seulement de la séquence définie par l'utilisateur, mais également de l'application réceptrice.
  • Par exemple, si Eclipse IDE a deux threads, un pour recevoir le flux d'erreur et un pour recevoir le flux system.out, ces threads ne sont pas sous votre contrôle et vous pouvez donc voir la séquence changer de temps en temps.
  • Si vous n'êtes pas préoccupé par les performances, vous pouvez dormir un peu entre les deux.

System.out.println("Out");

Thread.sleep(50);

System.err.println("error");


0 commentaires

0
votes

comme le disait Simeon Ikudabo, la tâche est impossible !! mais pour la plupart, essayez ce

static void print(PrintStream p, Object o) throws InterruptedException {
    Object lock = new Object();
    synchronized (lock) {

        Runnable r = new Runnable() {
            public void run() {
                synchronized (lock)
                {
                p.println(o);
                lock.notify();
                }
            }
        };
        new Thread(r).start();

        lock.wait();
    }

}

public static void main(String[] args) throws InterruptedException {

    for (int i = 0; i < 50; i++) {
        print(System.out, "out");
        print(System.err, "err");

    }}

vous pourriez le voir comme parfait, mais il y a encore une petite chance minuscule de sortir de la course et ce n'est pas non plus accordé.

p >


0 commentaires

1
votes

Même si vous videz vos flux après l'écriture, ces flux sont lus par différents threads dans Eclipse et si les écritures sont presque simultanément, il arrive que le thread de lecture de stderr soit exécuté avant le thread de stdout même si l'écriture correspondante dans stdout s'est produit en premier.

Depuis Java 1.5, il y a la classe ProcessBuilder et avec cela, elle pourrait être résolue dans Eclipse en redirigeant stderr vers stdout lors du lancement - mais la fonctionnalité d'Eclipse pour afficher la sortie stderr dans une couleur différente serait interrompue par cela.

Vous pouvez ajouter votre opinion sur https://bugs.eclipse.org /bugs/show_bug.cgi?id=32205


0 commentaires