java 运行时执行 python 脚本 raw_input
java runtime exec a python script with raw_input
我有一个运行 python 脚本的 java 程序(该脚本不是我的,因此无法更改)。
我是 运行 脚本:
Process p = Runtime.getRuntime().exec("python myScript.py");
该脚本有一个 "raw_input" 行需要用户输入。
我尝试使用
BufferedWriter userInput = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
userInput.write("myInput");
但这似乎不起作用;
另一件事,我正在使用
读取输出
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
List<String> output = new ArrayList();
while ((s = stdInput.readLine()) != null) {
output.add(s);
}
这在 python 脚本不需要任何输入时起作用,但是当存在 input_raw() 时,stdInput.readLine() 就卡住了。
python 脚本示例:
name = raw_input("What is your name? ")
print "your name is "+name
整个程序:
public static void main(String args[]) {
PythonRunner pr = new PythonRunner();
pr.start();
while(!pr.isFinished){
try {
System.out.println("waiting...");
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(String s:pr.result) System.out.println(s);
}
public class PythonRunner extends Thread {
public List<String> result;
public boolean isFinished;
public PythonRunner() {
result= new ArrayList<>();
isFinished = false;
}
@Override
public void run(){
try {
Process p = Runtime.getRuntime().exec("python myScript.py");
BufferedWriter userInput = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
userInput.write("myInput");
String s;
while ((s = stdInput.readLine()) != null) {
result.add(s);
}
isFinished=true;
}
catch (IOException e) {
isFinished=true;
}
}
}
编辑:
我设法使用
为脚本提供输入
userInput.write(cmd);
userInput.newLine();
userInput.flush();
但是,我仍然无法读取输出。一些脚本有输入-> 打印的无限循环。
例如,脚本:
stop = False
while not stop:
name = raw_input("")
print "your name is "+name
if name == "stop":
stop = True
当这个脚本运行时,我似乎无法读取已经给定名称的输出。只有当进程被赋予 "stop" 命令时,我才能读取整个输出。
你需要继承IO
https://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html#inheritIO()
Sets the source and destination for subprocess standard I/O to be the
same as those of the current Java process. This is a convenience
method. An invocation of the form
pb.inheritIO()
然后,您的流程执行可以采用以下形式
public class ProcessSample {
public static void main(String [] arg) throws Exception {
ProcessBuilder pb =
new ProcessBuilder("python", "script.py").inheritIO();
Process p = pb.start();
p.waitFor();
}
}
并且,使用您的脚本
name = raw_input("What is your name? ")
print "your name is "+name
你可以做到
> javac ProcessSample.java
> java -cp . ProcessSample
What is your name? a
your name is a
正在为 stdout 继承 IO
您始终可以将一些值传递给 Python 代码,同时从标准输出读取值 - 通过继承它。
import java.io.*;
public class PythonProcessRedirect {
public static void main(String [] arg) throws Exception {
ProcessBuilder pb =
new ProcessBuilder("python", "script_raw.py");
pb.redirectErrorStream(true);
pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
Process p = pb.start();
BufferedWriter writer = new BufferedWriter( new OutputStreamWriter( p.getOutputStream() ));
String input = "2\n";
writer.write(input);
writer.flush();
p.waitFor();
}
}
请注意,对于持续的数据流,您需要刷新它
import sys
import time
sys.stdout.write("give some input: ")
sys.stdout.flush()
time.sleep(2)
line = sys.stdin.readline()
sys.stdout.write("you typed: " + line)
sys.stdout.flush();
否则,数据将在 Python 刷新之前可用(例如,通过将缓冲区填充到限制)。
Stream Gobbler
您还可以使用 Stream Gobbler 和 运行 单独的线程 stdin/stdout/stderr。
import java.io.*;
public class PythonProcessStreamGobblerIO {
public static void main(String [] arg) throws Exception {
final Process p = Runtime.getRuntime().exec("python ./script_os.py" );
new Thread() {
public void run() {
try {
BufferedWriter writer = new BufferedWriter( new OutputStreamWriter( p.getOutputStream() ));
String input = "2\n";
writer.write(input);
writer.flush();
} catch(Exception ex) {
ex.printStackTrace();
}
}
}.start();
new Thread() {
public void run() {
try {
Reader reader = new InputStreamReader(p.getInputStream());
int data = -1;
while((data =reader.read())!= -1){
char c = (char) data;
System.out.print(c);
}
reader.close();
} catch(Exception ex) {
ex.printStackTrace();
}
}
}.start();
p.waitFor();
}
}
但是,同样,您必须确保(在 Python 端)标准输出已刷新。
我有一个运行 python 脚本的 java 程序(该脚本不是我的,因此无法更改)。 我是 运行 脚本:
Process p = Runtime.getRuntime().exec("python myScript.py");
该脚本有一个 "raw_input" 行需要用户输入。 我尝试使用
BufferedWriter userInput = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
userInput.write("myInput");
但这似乎不起作用;
另一件事,我正在使用
读取输出BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
List<String> output = new ArrayList();
while ((s = stdInput.readLine()) != null) {
output.add(s);
}
这在 python 脚本不需要任何输入时起作用,但是当存在 input_raw() 时,stdInput.readLine() 就卡住了。
python 脚本示例:
name = raw_input("What is your name? ")
print "your name is "+name
整个程序:
public static void main(String args[]) {
PythonRunner pr = new PythonRunner();
pr.start();
while(!pr.isFinished){
try {
System.out.println("waiting...");
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(String s:pr.result) System.out.println(s);
}
public class PythonRunner extends Thread {
public List<String> result;
public boolean isFinished;
public PythonRunner() {
result= new ArrayList<>();
isFinished = false;
}
@Override
public void run(){
try {
Process p = Runtime.getRuntime().exec("python myScript.py");
BufferedWriter userInput = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
userInput.write("myInput");
String s;
while ((s = stdInput.readLine()) != null) {
result.add(s);
}
isFinished=true;
}
catch (IOException e) {
isFinished=true;
}
}
}
编辑: 我设法使用
为脚本提供输入userInput.write(cmd);
userInput.newLine();
userInput.flush();
但是,我仍然无法读取输出。一些脚本有输入-> 打印的无限循环。 例如,脚本:
stop = False
while not stop:
name = raw_input("")
print "your name is "+name
if name == "stop":
stop = True
当这个脚本运行时,我似乎无法读取已经给定名称的输出。只有当进程被赋予 "stop" 命令时,我才能读取整个输出。
你需要继承IO
https://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html#inheritIO()
Sets the source and destination for subprocess standard I/O to be the same as those of the current Java process. This is a convenience method. An invocation of the form
pb.inheritIO()
然后,您的流程执行可以采用以下形式
public class ProcessSample {
public static void main(String [] arg) throws Exception {
ProcessBuilder pb =
new ProcessBuilder("python", "script.py").inheritIO();
Process p = pb.start();
p.waitFor();
}
}
并且,使用您的脚本
name = raw_input("What is your name? ")
print "your name is "+name
你可以做到
> javac ProcessSample.java
> java -cp . ProcessSample
What is your name? a
your name is a
正在为 stdout 继承 IO
您始终可以将一些值传递给 Python 代码,同时从标准输出读取值 - 通过继承它。
import java.io.*;
public class PythonProcessRedirect {
public static void main(String [] arg) throws Exception {
ProcessBuilder pb =
new ProcessBuilder("python", "script_raw.py");
pb.redirectErrorStream(true);
pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
Process p = pb.start();
BufferedWriter writer = new BufferedWriter( new OutputStreamWriter( p.getOutputStream() ));
String input = "2\n";
writer.write(input);
writer.flush();
p.waitFor();
}
}
请注意,对于持续的数据流,您需要刷新它
import sys
import time
sys.stdout.write("give some input: ")
sys.stdout.flush()
time.sleep(2)
line = sys.stdin.readline()
sys.stdout.write("you typed: " + line)
sys.stdout.flush();
否则,数据将在 Python 刷新之前可用(例如,通过将缓冲区填充到限制)。
Stream Gobbler
您还可以使用 Stream Gobbler 和 运行 单独的线程 stdin/stdout/stderr。
import java.io.*;
public class PythonProcessStreamGobblerIO {
public static void main(String [] arg) throws Exception {
final Process p = Runtime.getRuntime().exec("python ./script_os.py" );
new Thread() {
public void run() {
try {
BufferedWriter writer = new BufferedWriter( new OutputStreamWriter( p.getOutputStream() ));
String input = "2\n";
writer.write(input);
writer.flush();
} catch(Exception ex) {
ex.printStackTrace();
}
}
}.start();
new Thread() {
public void run() {
try {
Reader reader = new InputStreamReader(p.getInputStream());
int data = -1;
while((data =reader.read())!= -1){
char c = (char) data;
System.out.print(c);
}
reader.close();
} catch(Exception ex) {
ex.printStackTrace();
}
}
}.start();
p.waitFor();
}
}
但是,同样,您必须确保(在 Python 端)标准输出已刷新。