2011-03-30 4 views
0

J'ai un processus en cours d'exécution dans le thread (RunFile) et j'ai 2 threads pour travailler avec son stdin et stdout (WriteStdin, ReadStdout). Lorsque le processus écrit uniquement sur stdout et ne fonctionne pas avec stdin, tout est correct. Lorsque le processus écrit n'importe quoi dans stdout et attend l'entrée de stdin, ReadStdout n'écrit rien, jusqu'à ce que WriteStdin n'envoie pas de variable au processus. Quand le processus est terminé, ReadStdout imprime tout. Dans ce cas, j'ai besoin de ReadStdout fait la première liste, puis le processus en attente d'entrée de stdin.java: fonctionne avec stdin/stdout du processus en même temps

Cette classe crée un thread qui exécute le processus et crée également des threads ReadStdout et WriteStdin.

package bin; 

import java.io.IOException; 
import javax.swing.JTextArea; 

public class RunFile implements Runnable{ 

    public Thread program = null; 
    public Process process = null; 

    private JTextArea console; 

    public RunFile(JTextArea cons){ 
     console = cons; 

     program = new Thread(this); 
     program.start(); 
    } 

    public void run() {  
     try { 
      String exe = "path to executable file"; 

      process = Runtime.getRuntime().exec(exe); 

      ReadStdout read = new ReadStdout(process); 
      WriteStdin write = new WriteStdin(process, console); 

      process.waitFor(); 

      write.write.stop(); 
      read.read.stop(); 

      System.out.println("\nExit value: " + process.exitValue() + "\n"); 
     } 
     catch (InterruptedException e) {} 
     catch (IOException e1) {}  
    } 
} 

Cette classe crée un fil de discussion, qui fonctionne avec stdin de processus. Le fil est définitivement suspendu, est déclenchée que lorsque le moment a quelque chose à écrire à stdin

package bin; 

import java.io.BufferedWriter; 
import java.io.IOException; 
import java.io.OutputStreamWriter; 
import javax.swing.JTextArea; 
import javax.swing.text.BadLocationException; 

class WriteStdin implements Runnable{ 

    private Process process = null; 
    private JTextArea console = null; 
    public Thread write = null; 
    private String input = null; 
    private BufferedWriter writer = null; 

    public WriteStdin(Process p, JTextArea t){ 

     process = p; 
     console = t; 
     writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream())); 

     write = new Thread(this); 
     write.start(); 

     console.addKeyListener(new java.awt.event.KeyAdapter() { 
      public void keyTyped(java.awt.event.KeyEvent e){ 

       //save the last lines for console to variable input 
       if(e.getKeyChar() == '\n'){ 

        try {      
         int line = console.getLineCount() -2; 
         int start = console.getLineStartOffset(line); 
         int end = console.getLineEndOffset(line); 

         input = console.getText(start, end - start); 

         write.resume(); 

        } catch (BadLocationException e1) {} 
       } 
      } 
     }); 
    } 


    public void run(){ 
     write.suspend(); 
     while(true){ 
      try { 
       //send variable input in stdin of process 
       writer.write(input); 
       writer.flush(); 

      } catch (IOException e) {} 
      write.suspend(); 
     } 
    } 
} 

Cette classe créer un fil, qui fonctionne avec stdout du processus

package bin; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import javax.swing.JTextArea; 
import javax.swing.text.BadLocationException; 

class ReadStdout implements Runnable{ 

    public Thread read = null; 
    private BufferedReader reader = null; 
    private Process process = null; 

    public ReadStdout(Process p){ 

     process = p; 
     reader = new BufferedReader(new InputStreamReader(process.getInputStream())); 

     read = new Thread(this); 
     read.start(); 
    } 

    public void run() { 
     while(true){ 
     try { 
       String line = reader.readLine(); 
       if(line != null) 
        System.out.println (line); 
     } catch (IOException e) {} 
     }  
    } 
} 

Ceci est une source d'exemple (en C) des programmes que j'utiliser lors de la création de processus

#include <stdio.h> 
#include <stdlib.h> 

int main(void) { 

    for(int i=0; i<10; i++) 
    printf("%d\n", i); 

    char a[10]; 
    scanf("%s", a); 
    printf("%s\n",a); 

    for(int i=0; i<10; i++) 
    printf("%d\n", i); 

    return 0; 
} 
+0

Ceci est un * lot * de code à parcourir. Limitez-le à la plus petite partie qui peut aider les gens à comprendre votre problème. –

+2

Je vous déconseille fortement d'utiliser 'thread.stop()', mais plutôt de dire simplement à votre runnable de ne plus fonctionner (considérez une variable membre 'boolean running'). – corsiKa

+0

+1 pour la clause' thread.stop'. Pour ceux qui ne l'ont pas lu, le javadoc dit "obsolète" Cette méthode est intrinsèquement dangereuse L'arrêt d'un thread avec Thread.stop l'amène à déverrouiller tous les moniteurs qu'il a verrouillés (comme une conséquence naturelle de l'exception ThreadDeath non vérifiée propageant la pile.) Si l'un des objets précédemment protégés par ces moniteurs était dans un état incohérent, les objets endommagés deviennent visibles aux autres threads, ce qui peut entraîner un comportement arbitraire. " –

Répondre

0

J'ai une solution, sous Linux le processus doit créer ceci:Stdout n'est pas mis en mémoire tampon et mon programme fonctionne.

Questions connexes