为了方便灵活的做数据转换,决定用python写数据转换的方法,java通过Runtime.getRuntime().exec()调用python,因为参数的长度可能超过命令行的命令长度限制,不得已使用socket传参。
在调试过程中发现,如果分开调试python不使用java唤起而用命令行直接启动那么程序执行没有问题,如果使用java的Runtime.getRuntime().exec()唤起python,那么java读取socket输入流就会有问题,最后的几行数据始终读不到。
java程序如下
String[] arguments = new String[]{"python", scriptPath, o.toString()};
log.debug("脚本执行参数:{}", Arrays.asList(arguments));
runtime = Runtime.getRuntime();
process = runtime.exec(arguments);
Boolean re = process.waitFor(5, TimeUnit.SECONDS);
if (re) {
log.debug("the subprocess has exited");
if (process.exitValue() == 0) {
log.info("python执行完毕");
} else {
log.error("python执行失败:{}", process.exitValue());
throw new ServiceException("执行失败", -1);
}
} else {
log.debug("the subprocess has not exited");
}
后来发现如果加上对命令行输出读取代码后就正常了。。。百思不得其解
String[] arguments = new String[]{"python", scriptPath, o.toString()};
log.debug("脚本执行参数:{}",Arrays.asList(arguments));
runtime =Runtime.getRuntime();
process =runtime.exec(arguments);
process_read_thread_pool.execute(new
Runnable() {
@Override
public void run () {
try {
//读流
readProcessStream(process.getInputStream(), charset, "脚本输出");
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
});
process_read_thread_pool.execute(new
Runnable() {
@Override
public void run () {
try {
读流
readProcessStream(process.getErrorStream(), charset, "ERROR输出");
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
});
// 返回值为1表示调用python脚本失败,这和我们通常意义上见到的0与1定义正好相反
Boolean re = process.waitFor(5, TimeUnit.SECONDS);
if(re) {
log.debug("the subprocess has exited");
if (process.exitValue() == 0) {
log.info("python执行完毕");
} else {
log.error("python执行失败:{}", process.exitValue());
throw new ServiceException("执行失败", -1);
}
} else {
log.debug("the subprocess has not exited");
}
private void readProcessStream(InputStream inputStream, String charset, String type) throws IOException {
try (InputStreamReader isr = new InputStreamReader(inputStream, charset);
BufferedReader br = new BufferedReader(isr);) {
String line;
while ((line = br.readLine()) != null) {
// log.debug("{}输出:{}", type, line);
}
} finally {
log.debug("退出脚本{}",type);
inputStream.close();
}
}