做深度学习的项目需要用到Java调用Python。想了个办法,直接用Java运行cmd命令,执行.py文件。在此遇到了两个问题:
- 命令行的格式;
- 读取流的阻塞,就是能成功运行命令,且未从错误流读取数据,但什么读入都没有,一直显示在运行。(我用的jdk1.8,朋友的低版本无这个问题。)
问题二只存在于我的python运行时有复杂日志输出的情况(非我自己的print,应该是日志文件/warning的输出),所以java不能成功读取这种输出,造成流阻塞。
对于问题二,我的解决方法是用多线程分别读取数据流和错误命令流。
看了两天博客才解决的问题
感谢:csdn博主
感谢:知乎
在Java通过Runtime调用cmd运行命令
原版:
package test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class testProcessBulider {
public static void main(String[] args) throws IOException, InterruptedException {
// TODO Auto-generated method stub
Process proc;
try {
//proc = Runtime.getRuntime().exec("D:\\anaconda\\envs\\back-matting\\python.exe D:\\py\\test_gpu\\test_gpu.py");// 执行py文件
//D:\\py\\Background-Matting-master\\test_segmentation_deeplab.py -i sample_data/input
//这个语句可以在java版本更低的程序中运行
proc = Runtime.getRuntime().exec("D:\\anaconda\\envs\\back-matting\\python.exe D:\\py\\Background-Matting-master\\test_segmentation_deeplab.py");
//用输入输出流来截取结果
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream(),"utf-8"));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
BufferedReader ine = new BufferedReader(new InputStreamReader(proc.getErrorStream(),"utf-8"));
String linee = null;
while((linee = ine.readLine()) != null) {
System.out.println(linee);
}
ine.close();
System.out.println(proc.waitFor());
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
改进版:改用多线程处理读取正常数据流和读取异常数据流。
package test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class forPB {
public static void main(String[] args) {
try {
//"D:\\anaconda\\envs\\back-matting\\python.exe D:\\py\\test_gpu\\test_gpu.py"
//ProcessBuilder builder = new ProcessBuilder("adb", "logcat", "-d");
List<String> cmd = new ArrayList<String>();
//cmd.add("cmd");
cmd.add("D:\\anaconda\\envs\\back-matting\\python.exe");
cmd.add("D:\\py\\test_gpu\\test_gpu.py");
ProcessBuilder builder = new ProcessBuilder(cmd);
//ProcessBuilder builder = new ProcessBuilder("D:\\anaconda\\envs\\back-matting\\python.exe D:\\py\\test_gpu\\test_gpu.py");
// 重定向错误流到标准输出流
builder.redirectErrorStream(true);
// stdout
Process process = builder.start();
// start the process and start a new thread to handle the stream
// input
new Thread(new ProcessHandleRunnable(process)).start();
process.waitFor(); // wait if needed
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// mimics stream gobbler, but allows user to process the result
static class ProcessHandleRunnable implements Runnable {
private Process process;
public ProcessHandleRunnable(Process process) {
this.process = process;
}
public void run() {
BufferedReader br = null;
InputStreamReader reader = null;
try {
System.out.println("start run...");
reader = new InputStreamReader(process.getInputStream());
br = new BufferedReader(reader);
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
System.out.println("stop run...");
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
if (br != null)
br.close();
if (reader != null)
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}