2015-07-01 43 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:就緒,活動,暫停和以一組信號終止以管理和節點之間的通信] –