You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 22:52:55