2017-06-13 2 views
2

J'exécute un script à partir de Java avec le code suivant.Récupère STDOUT à partir de Runtime.getRuntime(). Exec() ligne par ligne plutôt que d'une seule fois

try (BufferedReader input = new BufferedReader(new InputStreamReader(Runtime.getRuntime() 
      .exec("ruby test.rb").getInputStream()))) { 
     String line = null; 
     while ((line = input.readLine()) != null) { 
      System.out.println("Got line: " + line); 
     } 
    } 

test.rb est simplement:

puts "one" 
sleep 1 
puts "two" 

Le problème est que tous l'entrée arrive dans le BufferedReader en même temps. Il devrait y avoir un délai d'une seconde entre les deux lignes. Y at-il un moyen de vider le Inputstream après chaque ligne dans le script?

Ce que je suis en train d'accomplir
Je veux appeler des scripts Ruby à partir d'une interface graphique Java et que la sortie du script apparaissent progressivement dans un textPane. En utilisant le code ci-dessus, STDOUT du script apparaît dans le panneau de texte tout à la fois lorsque le script se termine (et le Inputstream est probablement vidé).

Modifier:
Le problème était que Ruby était en train de mettre en mémoire tampon STDOUT. Fixé par $stdout.sync = true.

+2

Ajoutez '$ stdout.sync = true' à votre script ruby. –

+0

@SotiriosDelimanolis C'était tout. Merci beaucoup. Je savais que ça devait être quelque chose comme ça. – cilki

Répondre

-1

Avez-vous essayé Thread.sleep (1000) après System.out.println(). Vous devez attraper certaines InterruptedException. Votre éditeur vous le dira à coup sûr.

+0

Le sommeil pendant une seconde est juste un exemple. J'aurais en fait une tâche qui prendrait une quantité de temps inconnue à la place. – cilki

+0

Ok alors: ce n'est pas possible. Une idée consiste à placer un délimiteur dans ruby, le flux d'entrée Java l'attend. Mais ce ne sera pas si facile. Rappelez-vous que c'est juste un flux en Java. Ce flux ne peut pas savoir ce qui vient ensuite, donc vous devriez lui donner quelques drapeaux. – atmin