简体   繁体   English

使用 Java 中的 ProcessBuilder 将进程的输出重定向到另一个进程的输入

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

I have two processes defined by processBuilders:我有 processBuilders 定义的两个进程:

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

I want the output of pb1 to be the input to pb2 .我想要的输出pb1是输入到pb2 I found in the documentation that I can make the input of pb2 to be read from another process by using pipe:我在文档中发现我可以使用管道从另一个进程读取pb2的输入:

pb2.redirectInput(Redirect.PIPE);

However, how can I specify that I want this pipe to read from the output of pb1 ?但是,如何指定我希望此管道从pb1的输出中pb1

static ProcessBuilder.Redirect INHERIT Indicates that subprocess I/O source or destination will be the same as those of the current process. static ProcessBuilder.Redirect INHERIT 指示子进程 I/O 源或目标将与当前进程的 I/O 源或目标相同。

static ProcessBuilder.Redirect PIPE Indicates that subprocess I/O will be connected to the current Java process over a pipe. static ProcessBuilder.Redirect PIPE 指示子进程 I/O 将通过管道连接到当前 Java 进程。

So I don't think one of these will help you redirecting the output of one process to the input of another process.所以我认为其中一个不会帮助您将一个进程的输出重定向到另一个进程的输入。 You have to implement it yourself.你必须自己实现它。

Implementation:执行:

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();
}

}

This one can surely be designed nicer and I haven't tested, if it runs's safe, but it does the job.这个肯定可以设计得更好,我还没有测试过,如果它运行是安全的,但它可以完成工作。

Usage:用法:

RedirectStreams redirectStreams = new RedirectStreams(process1,process2);

Test:测试:

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();
    }
}
}

Output:输出:

Input process1: echo echo echo输入过程1:echo echo echo

Output process1 / Input process2:echo echo输出过程1 / 输入过程2:echo echo

Output process2: echo输出过程2:echo

As of JDK 9, you can use startPipeline like so:从 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