2015-07-01 44 views
2

如何重定向或获取系统输出到字符串?Java ProcessBuilder输出到字符串

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

for (...){ 
    pb.command(...); 
    pb.start(); 

    //here >>> assign output string to variable 
} 
+0

你有没有尝试过'pb.redirectOutput(ProcessBuilder.Redirect.appendTo(myFile));'? –

+1

可能的重复[如何将Process Builder的输出重定向到字符串?](http://stackoverflow.com/questions/16714127/how-to-redirect-process-builders-output-to-a-- string) – Chop

+0

我想要分配给一个变量进行处理,而不是文件。 –

回答

0

这里是关于如何将系统命令进程的标准输出捕获到字符串容器的意见。

Adapted from the web:

try { 
    ProcessBuilder pb = new ProcessBuilder("echo", "dummy io"); 
    final Process p=pb.start(); 
    BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream())); 
    String line; 
    StringBuilder sb = new StringBuilder(); 
    while((line=br.readLine())!=null) sb.append(line); 
} 

System.out.println(sb.toString()); 
0

在我原来在什么是基本I/O的一个很好的例子评论一致性。我破解了一些代码,并且比基本的功能还要多一些。


额外

  • 的环境shell变量和
  • 工作目录

这些功能添加 “配置文件式” 的执行你的系统命令。


基础工作

Java ThreadingJoining由Oracle。


代码

import java.io.BufferedReader; 
import java.io.File; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.OutputStream; 
import java.io.PrintWriter; 
import java.util.HashMap; 
import java.util.Map; 

/** 
* Created by triston on 11/2/17. 
*/ 

public class Commander { 

    private Commander(){} // no construction 

    public static class StreamHandler implements Runnable { 

    Object source; 
    Object destination; 

    StreamHandler(Object source, Object oDestination) { 
     this.source = source; this.destination = oDestination; 
    } 

    public void run() { 
     if (source instanceof InputStream) { 
     BufferedReader br = new BufferedReader(new InputStreamReader((InputStream) source)); 
     String line; 
     try { 
      while ((line = br.readLine()) != null) ((StringBuilder) destination).append(line + '\n'); 
     } catch (IOException oE) { 
     } 
     } else { 
     PrintWriter pw = new PrintWriter((OutputStream)destination); 
     pw.print((String)source); 
     pw.flush(); pw.close(); 
     } 
    } 

    public static Thread read(InputStream source, StringBuilder dest) { 
     Thread thread = new Thread(new StreamHandler(source, dest)); 
     (thread).start(); 
     return thread; 
    } 

    public static Thread write(String source, OutputStream dest) { 
     Thread thread = new Thread(new StreamHandler(source, dest)); 
     (thread).start(); 
     return thread; 
    } 

    } 

    static Map<String, String> environment = loadEnvironment(); 

    static String workingDirectory = "."; 

    static Map<String, String> loadEnvironment() { 
    ProcessBuilder x = new ProcessBuilder(); 
    return x.environment(); 
    } 

    static public void resetEnvironment() { 
    environment = loadEnvironment(); 
    workingDirectory = "."; 
    } 

    static public void loadEnvirons(HashMap input) { 
    environment.putAll(input); 
    } 

    static public String getEnviron(String name) { 
    return environment.get(name); 
    } 

    static public void setEnviron(String name, String value) { 
    environment.put(name, value); 
    } 

    static public boolean clearEnviron(String name) { 
    return environment.remove(name) != null; 
    } 

    static public boolean setWorkingDirectory(String path) { 
    File test = new File(path); 
    if (!test.isDirectory()) return false; 
    workingDirectory = path; 
    return true; 
    } 

    static public String getWorkingDirectory() { 
    return workingDirectory; 
    } 

    static public class Command { 

    ProcessBuilder processBuilder = new ProcessBuilder(); 
    Process process; 

    public Command(String... parameters) { 
     processBuilder.environment().putAll(environment); 
     processBuilder.directory(new File(workingDirectory)); 
     processBuilder.command(parameters); 
    } 

    public int start(String input, StringBuilder output, StringBuilder error) throws IOException { 

     // start the process 
     process = processBuilder.start(); 

     // start the error reader 
     Thread errorBranch = StreamHandler.read(process.getErrorStream(), error); 

     // start the output reader 
     Thread outputBranch = StreamHandler.read(process.getInputStream(), output); 

     // start the input 
     Thread inputBranch = StreamHandler.write(input, process.getOutputStream()); 

     int rValue = 254; 
     try { 
     inputBranch.join(); rValue--; 
     outputBranch.join(); rValue--; 
     errorBranch.join(); rValue--; 
     return process.waitFor(); 
     } catch (InterruptedException oE) { 
     oE.printStackTrace(); 
     return rValue; 
     } 

    } 

} 

测试

@Test public void foo() { 
    Command cmd = new Command("sh", "--"); 
    StringBuilder output = new StringBuilder(); 
    StringBuilder error = new StringBuilder(); 
    int pValue = 127; 
    try { 
    pValue = cmd.start("echo well done > /dev/stderr\n\necho oh, wow; false", output, error); 
    } catch (IOException oE) { 
    } 
    System.out.println("output: "+output.toString()); 
    System.out.println("error: "+error.toString()); 
    System.out.println("\nExit code: "+pValue); 
    System.exit(pValue); 
} 

自备packageJUnit注解。此示例代码演示返回值,命令输入,命令标准输出和命令错误输出。

我原来的设计,叫做主线程来执行标准输出处理。

祝您有美好的一天。

+0

此代码需要审查。这些线程理论的粉丝我不是。我无法理解为什么这些软件机器网络(线程)不能共同以“开箱即用”的方式共同执行。例如,IRC服务器实际上是管理多个线程和网络端点的并发通信的软件机器。也许,线程技术是基于一种很糟糕的方法,从远远超过以往。 –

+0

[同步=具有中间生命周期状态的que:就绪,活动,暂停和以一组信号终止以管理和节点之间的通信] –