如何将Process Builder的输出redirect到一个string?

我正在使用下面的代码来启动一个进程生成器。我想知道如何将其输出redirect到一个string。

ProcessBuilder pb = new ProcessBuilder(System.getProperty("user.dir")+"/src/generate_list.sh", filename); Process p = pb.start(); 

我尝试使用ByteArrayOutputStream但它似乎并没有工作。

InputStream读取。 你可以将输出追加到一个StringBuilder

 BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); StringBuilder builder = new StringBuilder(); String line = null; while ( (line = reader.readLine()) != null) { builder.append(line); builder.append(System.getProperty("line.separator")); } String result = builder.toString(); 

使用Apache Commons IOUtils,你可以在一行中完成:

 ProcessBuilder pb = new ProcessBuilder("pwd"); String output = IOUtils.toString(pb.start().getInputStream()); 

你可能会这样做:

 private static BufferedReader getOutput(Process p) { return new BufferedReader(new InputStreamReader(p.getInputStream())); } private static BufferedReader getError(Process p) { return new BufferedReader(new InputStreamReader(p.getErrorStream())); } ... Process p = Runtime.getRuntime().exec(commande); BufferedReader output = getOutput(p); BufferedReader error = getError(p); String ligne = ""; while ((ligne = output.readLine()) != null) { System.out.println(ligne); } while ((ligne = error.readLine()) != null) { System.out.println(ligne); } 

对于Java 7和8,这应该工作:

 private String getInputAsString(InputStream is) { try(java.util.Scanner s = new java.util.Scanner(is)) { return s.useDelimiter("\\A").hasNext() ? s.next() : ""; } } 

然后在你的代码中,这样做:

 String stdOut = getInputAsString(p.getInputStream()); String stdErr = getInputAsString(p.getErrorStream()); 

我无耻地偷偷从: 如何redirectProcess Builder的输出到一个string?

试图处理不同的情况(处理两个stderr和stdout,并没有阻止任何这些,超时后终止进程,正确地转义斜线,引号,特殊字符,空格,….)我放弃了,发现Apache Commons Exec的 https ://commons.apache.org/proper/commons-exec/tutorial.html这似乎是做所有这些事情很好。

我build议每个需要在java中调用外部进程的人使用Apache Commons Exec库,而不是重新创build它。

在java 8中有一个很好的lines()stream,你可以结合String.join和System.lineSeparator():

  try (BufferedReader outReader = new BufferedReader(new InputStreamReader(p.getInputStream())) { return String.join(System.lineSeparator(), outReader.lines().collect(toList())); \\ OR using jOOλ if you like reduced verbosity return Seq.seq(outReader.lines()).toString(System.lineSeparator()) } 

Java 8例子:

 public static String runCommandForOutput(List<String> params) { ProcessBuilder pb = new ProcessBuilder(params); Process p; String result = ""; try { p = pb.start(); final BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); StringJoiner sj = new StringJoiner(System.getProperty("line.separator")); reader.lines().iterator().forEachRemaining(sj::add); result = sj.toString(); p.waitFor(); p.destroy(); } catch (Exception e) { e.printStackTrace(); } return result; } 

用法:

 List<String> params = Arrays.asList("/bin/sh", "-c", "cat /proc/cpuinfo"); String result = runCommandForOutput(params); 

我使用这个确切的代码,它适用于单行或多行结果。 你也可以添加一个错误stream处理程序。

只需添加.inheritIO(); 到stream程生成器行。

IE:

ProcessBuilder pb = new ProcessBuilder(script.sh).inheritIO();