ProcessBuilder在使用多个参数时无法正常工作

8

我有一个ProcessBuilder:

String src = c:/hello/
String dst = c:/hello/2

ProcessBuilder builder = null;
builder = new ProcessBuilder("c:/file/file.exe", "-i", src, "-f", "-l 500", dst);
builder.redirectErrorStream(true);
process = builder.start();

问题在于只要我添加了"-l 500",就会输出:

"l 500"无效命令

尽管我输入的是"-l 500"而不是"l 500"。 如果我输入"--l 500",我会得到:

"-l 500"无效命令

尽管-l 500在命令提示符中运行时是有效的命令。

如果我移除"-l 500",它又能工作了。

我使用Processbuilder方式错了吗?

编辑:

好的,看起来如果我将"-l"和"500"作为单独的条目,像这样:

new ProcessBuilder("c:/file/file.exe", "-i", src, "-f", "-l", "500", dst);

为什么会这样?我不能使用带空格的命令作为同一条目吗?
3个回答

5
当你在命令提示符下运行它时,不需要将-l 500用引号括起来,因此它们被视为两个不同的参数。在命令行输入以下内容:

file.exe -i some_source -f "-l 500" some_dest

我期望你会看到与错误消息相同的错误,就像ProcessBuilder使用不正确时一样。 file.exe程序必须解析命令行,搜索具有前导-字符的字符串。 当它找到单个字符串"-l 500"时,它会删除-并且不将l 500识别为有效参数。 ProcessBuilder的一个参数类似于命令行中的带引号的参数。

@Omid,你是将它作为两个单独的参数传递给ProcessBuilder了吗? - hmjd
@Omid,但是file.exe不行。file.exe期望参数-l有一个关联的值,在这种情况下为500 - hmjd

5

我遇到了与ffmpeg命令相同的问题,其中有许多带值的参数。最终,我创建了一个ArrayList,并逐个将每个项目添加到列表中。以下是一个示例:

List<String> command = new ArrayList<>();
command.add(ffmpegCommand);
command.add("-re");
command.add("-i");
command.add(videoFile);
command.add("-vcodec");
command.add("libx264");
command.add("-vcodec");
command.add("libx264");
command.add("-vb");
command.add("500000");
command.add("-g");
command.add("60");
command.add("-vprofile");
command.add("main");
command.add("-acodec");
command.add("aac");
command.add("-ab");
command.add("128000");
command.add("-ar");
command.add("48000");
command.add("-ac");
command.add("2");
command.add("-vbsf");
command.add("h264_mp4toannexb");
command.add("-strict");
command.add("experimental");
command.add("-f");
command.add("mpegts");
command.add("udp://127.0.0.1:10000?pkt_size=1316");

ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectErrorStream(true);
Process process;
try {
  process = pb.start();
  process.waitFor();
  if (process.exitValue() == 0) {
    // success
  } else {
    // failure
  }
} catch (IOException | InterruptedException e) {
  // handle exception
}

其中ffmpegCommand是命令的完整路径,而videoFile是视频的完整路径。这是我成功运行该命令的唯一方法。


1

我认为ProcessBuilder的意图是帮助,但它并不直观,并且缺乏关于其行为的文档。无论如何,其他人的回答都是正确的,在这里我只是粘贴了一个小代码片段,以便更轻松地使用它。

String command = String.format("c:/file/file.exe -i %s -f -l 500 %s", src, dst);

ProcessBuilder ps = new ProcessBuilder(command.split(" "));

是的,按照平常的方式编写命令,然后使用 split 以便使用接收字符串列表的构造函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接