簡體   English   中英

使用 Java 中的 ProcessBuilder 將進程的輸出重定向到另一個進程的輸入

[英]Redirecting the output of a process into the input of another process using ProcessBuilder in Java

我有 processBuilders 定義的兩個進程:

ProcessBuilder pb1 = new ProcessBuilder (...)
ProcessBuilder pb2 = new ProcessBuilder (...)

我想要的輸出pb1是輸入到pb2 我在文檔中發現我可以使用管道從另一個進程讀取pb2的輸入:

pb2.redirectInput(Redirect.PIPE);

但是,如何指定我希望此管道從pb1的輸出中pb1

static ProcessBuilder.Redirect INHERIT 指示子進程 I/O 源或目標將與當前進程的 I/O 源或目標相同。

static ProcessBuilder.Redirect PIPE 指示子進程 I/O 將通過管道連接到當前 Java 進程。

所以我認為其中一個不會幫助您將一個進程的輸出重定向到另一個進程的輸入。 你必須自己實現它。

執行:

public class RedirectStreams {
public RedirectStreams(Process process1, Process process2) {
    final Process tmpProcess1 = process1;
    final Process tmpProcess2 = process2;
    new Thread(new Runnable() {
        @Override
        public void run() {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(tmpProcess1.getInputStream()));
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(tmpProcess2.getOutputStream()));
            String lineToPipe;

            try {

                while ((lineToPipe = bufferedReader.readLine()) != null){
                    System.out.println("Output process1 / Input process2:" + lineToPipe);
                    bufferedWriter.write(lineToPipe + '\n');
                    bufferedWriter.flush();
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();
}

}

這個肯定可以設計得更好,我還沒有測試過,如果它運行是安全的,但它可以完成工作。

用法:

RedirectStreams redirectStreams = new RedirectStreams(process1,process2);

測試:

public class ProcessPipeTest {
@Test public void testPipe(){
    try {

        Process process1 = new ProcessBuilder("/bin/bash").start();
        Process process2 = new ProcessBuilder("/bin/bash").start();

        RedirectStreams redirectStreams = new RedirectStreams(process1,process2);

        
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(process1.getOutputStream()));
        String command = "echo echo echo";
        System.out.println("Input process1: " + command);
        bufferedWriter.write(command + '\n');
        bufferedWriter.close();

        
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process2.getInputStream()));
        String actualOutput = bufferedReader.readLine();
        System.out.println("Output process2: " + actualOutput);
        assertEquals("echo",actualOutput);

    } catch (IOException e) {
        e.printStackTrace();
    }
}
}

輸出:

輸入過程1:echo echo echo

輸出過程1 / 輸入過程2:echo echo

輸出過程2:echo

從 JDK 9 開始,您可以像這樣使用startPipeline

ProcessBuilder.startPipeline(
    Arrays.asList(
        new ProcessBuilder(...),
        new ProcessBuilder(...),
        ...
    )
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM