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

时间:2022-01-27 20:47:47

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. I found in the documentation that I can make the input of pb2 to be read from another process by using pipe:

我希望pb1的输出成为pb2的输入。我在文档中发现我可以通过使用管道从另一个进程读取pb2的输入:

pb2.redirectInput(Redirect.PIPE);

However, how can I specify that I want this pipe to read from the output of pb1?

但是,如何指定我希望此管道从pb1的输出中读取?

1 个解决方案

#1


3  

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源或目标将与当前进程的相同。

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.

所以我认为其中一个不会帮助您将一个进程的输出重定向到另一个进程的输入。

So let's make our hands dirty and write some code. The relevant line is

所以让我们弄脏手写一些代码。相关的是

RedirectStreams redirectStreams = new RedirectStreams(process1,process2);

where the thread, with redirection, for the processes I/O's starts. The rest of the test method is just for demonstration. For the processes I start bash and output via echo command. So for this specific example I nested echo commands.

进程I / O启动时带有重定向的线程。测试方法的其余部分仅用于演示。对于进程,我启动bash并通过echo命令输出。因此,对于此特定示例,我嵌套了echo命令。

echo Foo

echo Foo

Foo

echo echo

回声回声

echo

回声

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

And here the RedirectStreams class, this one can surely be designed nicer and I haven't tested, if it runs's safe, but it does the job.

在这里RedirectStreams类,这个可以肯定设计得更好,我没有测试,如果它运行安全,但它完成了工作。

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

Input process1: echo echo echo

输入过程1:回声回声回声

Output process1 / Input process2:echo echo

输出过程1 /输入过程2:回声回声

Output process2: echo

输出过程2:回声

#1


3  

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源或目标将与当前进程的相同。

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.

所以我认为其中一个不会帮助您将一个进程的输出重定向到另一个进程的输入。

So let's make our hands dirty and write some code. The relevant line is

所以让我们弄脏手写一些代码。相关的是

RedirectStreams redirectStreams = new RedirectStreams(process1,process2);

where the thread, with redirection, for the processes I/O's starts. The rest of the test method is just for demonstration. For the processes I start bash and output via echo command. So for this specific example I nested echo commands.

进程I / O启动时带有重定向的线程。测试方法的其余部分仅用于演示。对于进程,我启动bash并通过echo命令输出。因此,对于此特定示例,我嵌套了echo命令。

echo Foo

echo Foo

Foo

echo echo

回声回声

echo

回声

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

And here the RedirectStreams class, this one can surely be designed nicer and I haven't tested, if it runs's safe, but it does the job.

在这里RedirectStreams类,这个可以肯定设计得更好,我没有测试,如果它运行安全,但它完成了工作。

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

Input process1: echo echo echo

输入过程1:回声回声回声

Output process1 / Input process2:echo echo

输出过程1 /输入过程2:回声回声

Output process2: echo

输出过程2:回声