-
public String python(String pythonPath, String[] params) {
-
File file =
new File(pythonPath);
-
if (!file.exists()){
-
return
"python脚本不存在!";
-
}
-
-
String[] command = Arrays.copyOf(
new String[]{
"python", pythonPath}, params.length +
2);
-
System.arraycopy(params,
0, command,
2, params.length);
-
-
List res =
new ArrayList<>();
-
try {
-
Process process = Runtime.getRuntime().exec(command,
null,
null);
-
process.waitFor();
-
-
Scanner scanner =
new Scanner(process.getInputStream());
-
while (scanner.hasNextLine()) {
-
String line = scanner.nextLine();
-
res.add(line);
-
}
-
-
}
catch (IOException e) {
-
e.printStackTrace();
-
}
catch (InterruptedException e) {
-
e.printStackTrace();
-
}
-
-
return
"success";
-
}
例子中,参数pythonPath就是python脚本的绝对路径,参数params是脚本的参数数组,command就是执行python命令字符串数组,格式就是python + 脚本 + 参数,构造好command后传入exec()中执行新进程,然后调用waitFor()函数等待进程结束,结束后从进程的输入流中获得脚本的输出结果存储到字符串数组中。
乍一看,上面的代码并没有问题,对于少量的输出结果执行后相当完美,但是当脚本的输出结果大小大于inputStream缓冲区大小时,程序会阻塞在waitFor()函数这里,问题就在于脚本的输出结果是在进程执行完之后才读取,一个好的解决办法就是新开一个清理线程来不断清空缓冲区,也就是输出和读取同时进行,代码如下:
-
public String python(String pythonPath, String[] params) {
-
File file =
new File(pythonPath);
-
if (!file.exists()){
-
return
"python脚本不存在!";
-
}
-
-
String[] command = Arrays.copyOf(
new String[]{
"python", pythonPath}, params.length +
2);
-
System.arraycopy(params,
0, command,
2, params.length);
-
-
List res =
new ArrayList<>();
-
try {
-
Process process = Runtime.getRuntime().exec(command,
null,
null);
-
-
ClearThread ct =
new ClearThread(process);
-
ct.start();
-
-
process.waitFor();
-
Thread.sleep(
1000);
-
-
ct.setEnd(
true);
-
res = ct.getRes();
-
}
catch (IOException e) {
-
e.printStackTrace();
-
}
catch (InterruptedException e) {
-
e.printStackTrace();
-
}
-
-
return
"success";
-
}
-
-
class ClearThread extends Thread {
-
Process process;
-
boolean end;
-
List res;
-
-
public ClearThread(Process process) {
-
this.process = process;
-
end =
false;
-
res =
new ArrayList<>();
-
}
-
-
@Override
-
public void run() {
-
if (process ==
null) {
-
return;
-
}
-
-
Scanner scanner =
new Scanner(process.getInputStream());
-
while (process !=
null && !end) {
-
while (scanner.hasNextLine()) {
-
String line = scanner.nextLine();
-
res.add(line);
-
}
-
}
-
}
-
-
public void setEnd(boolean end) {
-
this.end = end;
-
}
-
-
public List getRes() {
-
return res;
-
}
-
}