简体   繁体   English

ProcessBuilder 在使用多个参数时行为不正常

[英]ProcessBuilder not behaving properly with multiple arguments

I have a ProcessBuilder:我有一个 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();

The problem is that as soon as I add "-l 500" I get output:问题是,一旦我添加"-l 500"我就会得到输出:

"l 500" invalid command “l 500”无效命令

Even though I've inputed "-l 500" and not "l 500" .即使我输入了"-l 500"而不是"l 500" If I input "--l 500" I get:如果我输入"--l 500"我会得到:

"-l 500" invalid command “-l 500”无效命令

Even though -l 500 IS a valid command when running it in command prompt.即使-l 500在命令提示符下运行时它是一个有效的命令。

If I REMOVE "-l 500" it works again.如果我删除"-l 500"它会再次工作。

Am I using Processbuilder wrong?我使用 Processbuilder 错了吗?

EDIT:编辑:

Ok it seems as if it works if I do "-l" and "500" as separate entries like this:好的,如果我将“-l”和“500”作为单独的条目执行,似乎它可以工作:

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

Why is this so?为什么会这样? Can't I have a command with space in it as the same entry?我不能有一个带有空格的命令作为同一个条目吗?

When you run it at the command prompt you do not wrap the -l 500 in quotes, so they are treated as two different arguments.当您在命令提示符下运行它时,您不会将-l 500括在引号中,因此它们被视为两个不同的参数。 Enter this at the command line:在命令行输入:

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

and I expect you will see the same error message as you see when ProcessBuilder is used incorrectly.我希望您会看到与ProcessBuilder使用不当时看到的相同的错误消息。 The file.exe program must be parsing the command line, searching for strings with a leading - character. file.exe程序必须解析命令行,搜索带有前导-字符的字符串。 When it finds the single string "-l 500" it removes the - and does not recognise l 500 as a valid argument.当它找到单个字符串"-l 500"它会删除-并且不会将l 500识别为有效参数。

An argument to ProcessBuilder is analogous to a quoted argument on the command line. ProcessBuilder的参数类似于命令行上的带引号的参数。

I ran into the same issue with the ffmpeg command where I have many paramters with values.我在使用 ffmpeg 命令时遇到了同样的问题,其中我有许多带有值的参数。 I ended up creating an ArrayList and the adding each item to the list one by one.我最终创建了一个 ArrayList 并将每个项目一项一项地添加到列表中。 Here is an example:下面是一个例子:

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
}

Where ffmpegCommand is the full path to the command and videoFile is the full path to the video.其中ffmpegCommand是命令的完整路径, videoFile是视频的完整路径。 This is the only way that I was able to get the command to run successfully.这是我能够让命令成功运行的唯一方法。

I think the intention of ProcessBuilder was to help but it is not intuitive and it lacks documentation about how it behaves.我认为 ProcessBuilder 的目的是提供帮助,但它并不直观,并且缺乏有关其行为方式的文档 Anyways what others answered is true, here I am just pasting a small code snipped on how to use it without struggling too much.无论如何,其他人的回答是正确的,在这里我只是粘贴了一个关于如何使用它而没有太多挣扎的小代码。

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

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

Yep, write your command as you usually do then use split in order to use the constructor that receives a list of strings.是的,像往常一样编写命令,然后使用split以使用接收字符串列表的构造函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM