通过processbuilder进行多进程通信,冻结readline()for BufferedReader()

时间:2015-04-12 05:56:41

标签: java multithreading bufferedreader processbuilder bufferedwriter

我试图允许一个程序(程序启动程序,如果你愿意)和它通过processbuilder启动的程序之间的通信。我的输出工作正常,但输入似乎在helloworld(创建的进程)中到达readline()方法时停止。

以下是helloworld.java:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;


public class helloworld {
public static void main (String[] args) {
System.out.println ("println(\"Hello World!\")");
System.out.println ("getInput()");
Scanner in = new Scanner(System.in);
BufferedReader br = new BufferedReader(
        new InputStreamReader(System.in));
String input = "";
try {
    // wait until we have data to complete a readLine()
    while (!br.ready()) {
      Thread.sleep(200);
    }
    System.out.println("println(\"Attempting to resolve input\")");
    input = br.readLine();  

^这是程序挂起^

的地方
    if(input != null){
        System.out.println("println(\"This should appear\")");
    }
    System.out.println("println(\"input recieved " + input + "\")");
} catch (InterruptedException | IOException e) {
    System.out.println("ConsoleInputReadTask() cancelled");
  }

System.out.println("println(\"You said: " + input + "\")");
//System.out.println("println(\"You said: " + in. + "!\")");

in.close();
System.exit(0);
}
}

这是收到其他流程的输出(println)的地方:

public void run() {
    try {
        //cfile = files[indexval].getAbsolutePath();
        String[] commands = 
            {
                "java", //Calling a java program
                "-cp" , //Denoting class path
                cfile.substring(0,cfile.lastIndexOf(File.separator) ), //File path
                program}; //Class name

        ProcessBuilder probuilder = new ProcessBuilder( commands );

        //start the process
        Process process = probuilder.start();

        //Read out dir output
        //probuilder.inheritIO(); //Can inherit all IO calls
        InputStream is = process.getInputStream();
        OutputStream os = process.getOutputStream();
        InputStreamReader isr = new InputStreamReader(is);
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
        BufferedReader br = new BufferedReader(isr);
        String line;
        /*System.out.printf("Output of running %s is:\n",
                Arrays.toString(commands));*/
        while ((line = br.readLine()) != null) {
            myController.runCommand(line, "Please enter something!", bw);
            //System.out.println(line);
        }
        br.close();
        os.close();
        } catch (IOException e){
            e.printStackTrace();
        }
    System.out.println("programclosed");
}

以下是它调用的函数:

public synchronized void runCommand(String line, Object... arguments) throws     IOException {
    String[] tokens;
    if(line.contains("(")){
        tokens = line.split("\\(",2);

    switch(tokens[0]){
    case "println": //Println - format println(String strng)
        tokens[1] = tokens[1].substring(1, tokens[1].length() - 2);
        System.out.println(tokens[1]);
        break;
    case "getInput": //Get input - format getInput(String command, String message, BufferedWriter br)
        Scanner reader = new Scanner(System.in);
        System.out.println(arguments.length);
        System.out.println(((String)arguments[0]));
        BufferedWriter in = ((BufferedWriter)arguments[1]);
        in.write(reader.nextLine());
        System.out.println("sending input");
        in.flush();
        reader.close();
        break;
    default:
        System.out.println("Invalid command recieved!");
    }
    } else
        System.out.println("Invalid command recieved!");


}

我收到的输出是:

  

Hello World!

     

2   请输入一些内容!

     

这是测试输入

     

发送输入

     

尝试解决输入

如您所见,我成功退出while(!br.ready())循环,然后停在br.readLine();

我知道inheritIO()存在,但是对于这种情况,我使用BufferedOuput来发送命令,然后将这些命令解析并发送到switch语句,后者又调用相应的函数。这是因为可以从流程管理器启动多个流程,想想多个System.in调用到达时的乐趣,没有什么可以确定它的流程!另外,这允许我调用任何类型的函数,甚至是那些与println或输入无关的函数。

1 个答案:

答案 0 :(得分:1)

我认为这里的问题是以下结果:

    如果有任何可供阅读的字符,则
  1. BufferedReader.ready()会返回true。它并不保证其中有任何回车。 (docs
  2. BufferedReader.readLine()寻找回车以完成一条线。如果找不到,则会阻止。
  3. BufferedWriter.write()不会自动写入终止回车。
  4. 要测试这是否确实存在问题,请在runCommand()

    中替换此行
    in.write(reader.nextLine());
    

    使用:

    in.write(reader.nextLine() + "\n");