阅读system.in时的Runtime.exec永远不会返回(Runtime.exec never

2019-09-20 11:42发布

下面是我的示例代码,我想在运行一个新的子进程来处理从标准输入的命令。 但是,如果我读了system.in exec方法永远不会返回。 在EXEC命令()非常简单,没有任何与标准输入。

我想了解一下有没有什么办法解决? 我如何开始一个新的子进程而启动另一个线程读取标准输入?

public static void main(String[] args){
    new Thread(new Runnable(){
        public void run(){
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            String command = null;
            try{
                while((command = reader.readLine()) != null){
                    System.out.println("Command Received:" + command);
                }
            }catch(Exception ex){
                ex.printStackTrace();
                //failed to listening command
            }

        }
    }).start();
    Process process = null;
    try {
        process = Runtime.getRuntime().exec("java -cp C:/agenttest Test");
        System.out.println("never returns");
        process.waitFor();
    } catch (IOException e) {
        throw new RuntimeException( e );
    } catch (InterruptedException e) {
        throw new RuntimeException( e );
    }
}

测试类很简单,这里是Test.java

public static void main(String[] args){
    System.out.println("Standard out");
    System.out.println("Standard out");
    System.err.println("Standard err");
    System.out.println("Standard out");
    try{
        Thread.sleep(10000);
    }catch(InterruptedException ex){}
}

Answer 1:

这个问题可能是你没有处理错误流和输入流,并超越平台的缓冲区。 尝试处理该输出按照著名的文章, 当的Runtime.exec()不会 。

例如:

import java.io.*;

public class TestMain {
   private static final String JAVA_CMD = "java";
   private static final String CP = "-cp";

   // *** your CLASS_PATH and PROG Strings will of course be different ***
   private static final String CLASS_PATH = "C:/Users/hovercraft/Documents/workspace/Yr 2012A/bin";
   private static final String PROG = "yr12.m07.b.Test2";

   private static final String[] CMD_ARRAY = { JAVA_CMD, CP, CLASS_PATH, PROG };

   public static void main(String[] args) {
      new Thread(new Runnable() {
         public void run() {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                  System.in));
            String command = null;
            try {
               while ((command = reader.readLine()) != null) {
                  System.out.println("Command Received:" + command);
               }
            } catch (Exception ex) {
               ex.printStackTrace();
               // failed to listening command
            }

         }
      }).start();
      Process process = null;
      try {
         ProcessBuilder processBuilder = new ProcessBuilder(CMD_ARRAY);
         process = processBuilder.start();
         InputStream inputStream = process.getInputStream();
         setUpStreamGobbler(inputStream, System.out);

         InputStream errorStream = process.getErrorStream();
         setUpStreamGobbler(errorStream, System.err);

         System.out.println("never returns");
         process.waitFor();
      } catch (IOException e) {
         throw new RuntimeException(e);
      } catch (InterruptedException e) {
         throw new RuntimeException(e);
      }
   }

   public static void setUpStreamGobbler(final InputStream is, final PrintStream ps) {
      final InputStreamReader streamReader = new InputStreamReader(is);
      new Thread(new Runnable() {
         public void run() {
            BufferedReader br = new BufferedReader(streamReader);
            String line = null;
            try {
               while ((line = br.readLine()) != null) {
                  ps.println("process stream: " + line);
               }
            } catch (IOException e) {
               e.printStackTrace();
            } finally {
               try {
                  br.close();
               } catch (IOException e) {
                  e.printStackTrace();
               }
            }
         }
      }).start();
   }
}


Answer 2:

你应该保持读取输入流,否则会被封锁。 它无关,与JVM但underyling操作系统。



文章来源: Runtime.exec never returns when reading system.in