关于r:Java getRuntime.exec()-错误流中的“致命错误:没有这样的文件或目录”(无例外)

Java getRuntime.exec() - “Fatal error: no such file or directory” in error stream (no exception)

当我尝试使用getRuntime()。exec在Java(rJava)中执行R脚本时,如在下面的代码中可以看到的那样,该过程的错误流将引发错误消息"严重错误:无法打开文件PID_controller3.R : 无此文件或目录。"。 没有引发异常-当我尝试通过shell在同一目录中使用Rscript执行脚本时,一切正常。 有谁知道这里有什么问题吗?

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
try {
    Process p = Runtime.getRuntime().exec("C:\\Program Files\
\
-3.3.0\\bin\
script"
+"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());}


从OS进行查看时,除非另有说明,否则某个进程是从另一个进程派生的,并继承该进程的所有属性。 了解系统中的所有进程都是树的一部分。 该规则的唯一例外是根进程,它也是树的根,即使对于OS也具有特殊含义。

在继承的属性中有工作目录。 例如,在外壳中,您可以输入:

1
$ ls someFile

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

以您的情况来看,您希望处理的文件不在您创建的进程的当前工作目录中。 Java的Runtime不允许您更改此设置。

但是ProcessBuilder可以:

1
2
3
4
5
6
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()