如何将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();