Java getRuntime.exec() - "致命错误:没有这样的文件或目录"在错误流中(没有例外)

时间:2016-08-07 13:57:40

标签: java r runtime.exec

当我尝试使用getRuntime()。exec在Java(rJava)中执行R-Script时,因为它可以在下面的代码中看到,然后进程的错误流抛出错误消息"致命错误:无法打开文件PID_controller3.R:没有这样的文件或目录。"。抛出没有异常 - 当我尝试通过shell在同一目录中使用Rscript执行脚本时,一切正常。有没有人知道这里有什么问题?

例如,当我将java代码中脚本的路径更改为不存在的路径时,抛出一个IOException。使用正确的路径时不会发生这种情况,但我收到此错误消息,该消息包含在进程的错误流中。

try {
    Process p = Runtime.getRuntime().exec("C:\\Program Files\\R\\R-3.3.0\\bin\\Rscript " + "PID_controller3.R");

    BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
    String line;
    while((line = br.readLine()) != null)
        System.out.println("Read error stream: \"" + line + "\"");

        int code = p.waitFor();

        switch (code) {
        case 0:
            //normal termination, everything is fine
            Log.printLine(code);
            break;
        default:
            Log.printLine(code);
        }
    }
    catch (Exception ie){ System.out.println(ie.toString());}

1 个答案:

答案 0 :(得分:1)

从操作系统查看时,除非另有说明,否则进程将从另一个进程分叉并继承该进程的所有属性。了解系统中的所有进程都是树的一部分。此规则的唯一例外是根进程,它也是树的根,甚至对操作系统也有特殊含义。

继承的属性是工作目录。例如,在shell中,您可以键入:

$ ls someFile

shell,其提示符在此处可见($)具有给定的工作目录;命令(ls someFile)将假定shell的工作目录中有一个名为someFile的文件(因为启动执行ls命令的进程继承它)。

在您的情况下,事实证明您要处理的文件不在您创建的进程的当前工作目录中。 Java Runtime不允许您更改此内容。

ProcessBuilder确实:

final Path workingDir = Paths.get("path/to/working/dir");

final ProcessBuilder pb = new ProcessBuilder("path/to/command", "thefile")
    .directory(workingDir.toFile());

// obtain a Process using pb.exec()