Java调用R脚本中途停滞问题求助(Runtime.getRuntime()+RScript)
问题:Java调用R脚本中途停止输出
我通过Java的Runtime.getRuntime()结合RScript调用R脚本,代码运行过程中会中途停止输出,但直接在命令行运行该R脚本可正常执行完毕。不确定问题出在RScript、BufferedReader还是Runtime.getRuntime().exec(),恳请帮助。
原始Java代码
package org.nachc.tools.fhirtoomop.tools.build.postgres.build; import java.io.BufferedReader; import java.io.File; import java.io.InputStreamReader; import com.nach.core.util.file.FileUtil; import lombok.extern.slf4j.Slf4j; @Slf4j public class ETLSYN01_LoadSynthFiles { public static void main(String[] args) { exec(); } public static void exec() { try { log.info("\n\n\n-----------------------------------"); log.info("LOADING TEST DATA USING ETL-Synthea R-SCRIPTS"); // 获取要运行的文件 File file = FileUtil.getFile("/postgres/build/r/load-synthea-files.R"); String path = FileUtil.getCanonicalPath(file); String cmd = "Rscript " + path; log.info("获取到文件: " + path); log.info("执行命令: " + cmd); // 通过Runtime运行R脚本 Runtime rt = Runtime.getRuntime(); Process proc = rt.exec(cmd); // 读取标准输出 BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream())); String s = null; while ((s = stdInput.readLine()) != null) { log.info(s); } // 读取错误输出 BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream())); System.out.println("命令的标准错误输出(若有):\n"); while ((s = stdError.readLine()) != null) { log.info(s); } log.info("执行完成。"); } catch(Exception exp) { throw (new RuntimeException(exp)); } } }
补充信息
若在R脚本中添加sink输出到文件,Java进程仍持续运行,但文件输出会在与控制台输出相同的位置停止:
sink(file="./SINK.TXT") ...<我的代码> sink(file=NULL)
临时解决办法
通过调用.bat文件执行RScript可使脚本正常运行完毕,相关代码如下:
package org.nachc.tools.fhirtoomop.tools.build.postgres.build; import java.io.BufferedReader; import java.io.File; import java.io.InputStream; import java.io.InputStreamReader; import org.yaorma.util.time.Timer; import com.nach.core.util.file.FileUtil; import lombok.extern.slf4j.Slf4j; @Slf4j public class ACH1_RunAchilles { public static void main(String[] args) { exec(); } public static void exec() { Timer timer = new Timer(); timer.start(); // runRScript(FileUtil.getFile("/postgres/build/r/achilles/install-achilles.r")); File file = FileUtil.getFile("/postgres/build/r/achilles/run-achilles.bat"); String fileName = FileUtil.getCanonicalPath(file); log.info("文件路径: " + fileName); try { Runtime. getRuntime(). exec("cmd /c start \"\" " + fileName); } catch (Exception exp) { throw new RuntimeException(exp); } log.info("ACHILLES执行耗时: " + timer.getElapsedString()); log.info("Achilles执行完成。"); } private static void runRScript(File file) { try { log.info("\n\n\n-----------------------------------"); log.info("通过R脚本运行ACHILLES"); // 获取要运行的文件路径 String path = FileUtil.getCanonicalPath(file); String cmd = "Rscript " + path; log.info("获取到文件: " + path); log.info("执行命令: " + cmd); // 通过Runtime运行R脚本 Runtime rt = Runtime.getRuntime(); Process proc = rt.exec(cmd); // 读取标准输出 BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream())); String s; s = null; while ((s = stdInput.readLine()) != null) { log.info(s); } log.info("Achilles主逻辑执行完成,检查是否有错误..."); // 读取错误输出 BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream())); System.out.println("命令的标准错误输出(若有):\n"); s = null; boolean hasErrors = false; while ((s = stdError.readLine()) != null) { if (hasErrors == false) { hasErrors = true; log.error("执行过程中出现错误"); } log.info(s); } log.info("R脚本处理完成"); } catch (Exception exp) { throw (new RuntimeException(exp)); } } }
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

