多进程通过processbuilder通信,冻结在readline() for BufferedReader()
Multiprocess via processbuilder Communication, freeze at readline() for BufferedReader()
我试图允许一个程序(程序启动器,如果你愿意的话)和它通过 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
Please enter something!
This is a test input
sending input
Attempting to resolve input
如您所见,我成功退出了 while(!br.ready()) 循环,并在 br.readLine();
处停止
我知道 inheritIO() 存在,但对于这种情况,我使用 BufferedOuput 发送命令,然后解析这些命令并将其发送到 switch 语句,后者又调用相应的函数。这是因为可以从进程管理器启动多个进程,想想当多个 System.in 调用到达时的乐趣,没有什么可以确定它是哪个进程!此外,这允许我调用任何类型的函数,甚至是那些与 println 或输入无关的函数。
我认为这里的问题是由以下原因造成的:
BufferedReader.ready()
returns true
如果有任何字符可供读取。不保证其中有回车return。 (docs)
BufferedReader.readLine()
寻找回车 return 来完成一行。如果找不到,它会阻止。
BufferedWriter.write()
不会自动写入终止回车 return.
要测试这是否真的是问题所在,请将 runCommand()
中的这一行替换为:
in.write(reader.nextLine());
与:
in.write(reader.nextLine() + "\n");
我试图允许一个程序(程序启动器,如果你愿意的话)和它通过 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 Please enter something!
This is a test input
sending input
Attempting to resolve input
如您所见,我成功退出了 while(!br.ready()) 循环,并在 br.readLine();
处停止我知道 inheritIO() 存在,但对于这种情况,我使用 BufferedOuput 发送命令,然后解析这些命令并将其发送到 switch 语句,后者又调用相应的函数。这是因为可以从进程管理器启动多个进程,想想当多个 System.in 调用到达时的乐趣,没有什么可以确定它是哪个进程!此外,这允许我调用任何类型的函数,甚至是那些与 println 或输入无关的函数。
我认为这里的问题是由以下原因造成的:
BufferedReader.ready()
returnstrue
如果有任何字符可供读取。不保证其中有回车return。 (docs)BufferedReader.readLine()
寻找回车 return 来完成一行。如果找不到,它会阻止。BufferedWriter.write()
不会自动写入终止回车 return.
要测试这是否真的是问题所在,请将 runCommand()
中的这一行替换为:
in.write(reader.nextLine());
与:
in.write(reader.nextLine() + "\n");