Run external program concurrently and communicate with it through stdin / stdout

后端 未结 5 1804
耶瑟儿~
耶瑟儿~ 2020-12-06 07:17

I want to be able to run an external program concurrently with my Java code, i.e. I want to start the program, then return control to the calling method while keeping the ex

相关标签:
5条回答
  • 2020-12-06 07:47

    YOu can launch the external app with Runtime.getRuntime().exec(...)

    To send data to the external program, you can either send data on the Processes output stream (You get a Process object back from exec) or you can open sockets and communicate that way.

    0 讨论(0)
  • 2020-12-06 07:57

    I second the answer about using ProcessBuilder. If you want to know more details about this, and why you should prefer it to Runtime.exec(), see this entry in the Java glossary. It also shows how to use threads to communicate with the external process.

    0 讨论(0)
  • 2020-12-06 08:02

    Have a look at ProcessBuilder. Once you've set up the ProcessBuilder and executed start you'll have a handle to a Process to which you can feed input and read output.

    Here's a snippet to get you started:

    ProcessBuilder pb = new ProcessBuilder("/bin/bash");
    Process proc = pb.start();
    
    // Start reading from the program
    final Scanner in = new Scanner(proc.getInputStream());
    new Thread() {
        public void run() {
            while (in.hasNextLine())
                System.out.println(in.nextLine());
        }
    }.start();
    
    // Write a few commands to the program.
    PrintWriter out = new PrintWriter(proc.getOutputStream());
    out.println("touch hello1");
    out.flush();
    
    out.println("touch hello2");
    out.flush();
    
    out.println("ls -la hel*");
    out.flush();
    
    out.close();
    

    Output:

    -rw-r--r-- 1 aioobe aioobe 0 2011-04-08 08:29 hello1
    -rw-r--r-- 1 aioobe aioobe 0 2011-04-08 08:29 hello2
    
    0 讨论(0)
  • I had issues trying to achieve bidirectional communication with the external process through stdin/stdout, because of blocking. In the end I found a github gist which allowed me solve the issue simply and elegantly; that gist is actually based on a stackoverflow answer.

    See that other answer for sample code, but the core of the idea is to set up an event loop for reading and writing (while loop with 10ms sleeping), and using low-level stream operations so that no caching and blocking is going on -- only try to read if you know the other process in fact wrote something (through InputStream.available()).

    It leads to a bit strange programming style, but the code is much simpler than it would be if using threads, and does the job pretty well.

    0 讨论(0)
  • 2020-12-06 08:13

    I think you will find the Javadoc for class java.lang.Process helpful. Of note, you can get the input and output streams from a Process to communicate with it while it is running.

    0 讨论(0)
提交回复
热议问题