2016-11-29 54 views
1

我有一个shell脚本,它有一些命令,其中一个命令期望在运行时输入一些数据。我使用exec()方法运行这个shell脚本。目前,我正在手动输入数据,如果它要求输入。以下是我的代码,在java程序中运行时从控制台写入和读取数据

  Process p = Runtime.getRuntime().exec("myshellscript"); 

      BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream())); 

      BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream())); 

      // read the output from the command 
      System.out.println("Here is the standard output of the command:\n"); 
      while ((s = stdInput.readLine()) != null) { 
       System.out.println(s); 
      } 

      // read any errors from the attempted command 
      System.out.println("Here is the standard error of the command (if any):\n"); 
      while ((s = stdError.readLine()) != null) { 
       System.out.println(s); 
      } 

      System.exit(0); 

我想要做的就是输入时控制台预期的数据,应该由java程序进入,只是继续我进一步的java程序。

回答

2

这是我做的:

  1. 创建两个线程将从p.getInputStream()和p.getErrorStream()读取,
  2. 写入数据p.getOutputStream(),
  3. 等待两个线程终止(与join()方法)

编辑:

public class Main { 
    private static final Logger LOG = Logger.getLogger(Main.class.getName()); 

    public static void main(String[] args) { 
     try { 
      Process p = Runtime.getRuntime().exec("myshellscript"); 
      Thread outHandler = new OutputHandler(p.getInputStream(), "UTF-8"); 
      outHandler.setDaemon(true); 
      outHandler.start(); 
      Thread errHandler = new OutputHandler(p.getErrorStream(), "UTF-8"); 
      errHandler.setDaemon(true); 
      errHandler.start(); 
      sendInput(p, "the input data", "UTF-8"); 
      int result = p.waitFor(); 
      outHandler.join(); 
      errHandler.join(); 
      System.out.println("exit code: " + result); 
     } catch (IOException ex) { 
      LOG.log(Level.SEVERE, null, ex); 
     } catch (InterruptedException ex) { 
      LOG.log(Level.SEVERE, null, ex); 
     } 
    }  

private void sendInput(Process process, String input, String encoding) 
     throws IOException { 

    try (OutputStream stream = process.getOutputStream(); 
      Writer writer = new OutputStreamWriter(
        stream, encoding == null ? "UTF-8" : encoding); 
      PrintWriter out = new PrintWriter(writer)) { 
     if (input != null) { 
      Reader reader = new StringReader(input); 
      BufferedReader in = new BufferedReader(reader); 
      String line = in.readLine(); 
      while (line != null) { 
       out.println(line); 
       line = in.readLine(); 
      } 
     } 
    } 
} 

    private static class OutputHandler extends Thread { 
     private BufferedReader in; 

     private OutputHandler(InputStream in, String encoding) 
       throws UnsupportedEncodingException { 
      this.in = new BufferedReader(new InputStreamReader(
        in, encoding == null ? "UTF-8" : encoding)); 
     } 

     @Override 
     public void run() { 
      try { 
       String s = in.readLine(); 
       while (s != null) { 
        System.out.println(s); 
        s = in.readLine(); 
       } 
      } catch (IOException ex) { 
       LOG.log(Level.SEVERE, null, ex); 
      } finally { 
       try { 
        in.close(); 
       } catch (IOException ex) { 
        LOG.log(Level.SEVERE, null, ex); 
       } 
      } 
     } 
    } 
} 
+0

能否请你简单介绍一下我对java新手的代码,我从来没有用过多线程。 –

+1

Here you go .... –

+0

请注意,如果您使用ProcessBuilder,则可以执行redirectErrorStream(true),并且只需要一个线程。 –