java:同时使用stdin / stdout进程

时间:2011-03-30 22:13:11

标签: java

我在线程(RunFile)中运行进程,我有2个线程可以使用他的stdin和stdout(WriteStdin,ReadStdout)。当进程只写入stdout而不使用stdin时,一切都是正确的。 当进程向stdout写任何东西并等待stdin的输入时,ReadStdout不会写任何东西,直到WriteStdin没有向进程发送变量。当进程退出时,然后ReadStdout打印所有。在这种情况下,我需要ReadStdout进行第一个列表,然后等待来自stdin的输入。

此类创建一个运行该进程的Thread,并创建线程ReadStdout和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) {}       
    }
}

此类创建一个与进程的stdin一起使用的线程。 线程被永久挂起,仅在有时间写入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();
        }
    }
}

此类创建一个线程,该线程使用进程的stdout

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) {}
        }       
    }
}

这是我在创建流程时使用的程序的示例源(在C中)

#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;
}

1 个答案:

答案 0 :(得分:0)

我有一个解决方案,在Linux中,流程必须创建:

String exe = "absolute path to executable file";
ProcessBuilder builder = new ProcessBuilder();
builder.command().add("bash");
builder.command().add("-c");
builder.command().add("stdbuf -o0 " + exe);
builder.redirectErrorStream(true);
Process process = builder.start();

Stdout没有缓冲,我的程序正常工作。