2017-02-20 198 views
1

我尝试在java中执行windows命令cmd,给它提供命令并在控制台上输出输出或错误。但是,我的企图在打印横幅消息后挂起。这是代码。java Runtime.exec运行交互式shell挂起

import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.OutputStream; 
import java.io.OutputStreamWriter; 

public class Application { 

    public static void main(String[] args) throws IOException, InterruptedException { 

     Process exec = Runtime.getRuntime().exec("cmd"); 

     InputStream procOut = exec.getInputStream(); 
     InputStream procErrOut = exec.getErrorStream(); 
     OutputStream procIn = exec.getOutputStream(); 

     new StreamConsumer(procOut).run(); 
     new StreamConsumer(procErrOut).run(); 

     ByteArrayOutputStream byos = new ByteArrayOutputStream(); 
     byos.write("ping 1.1.1.1".getBytes()); 
     byos.writeTo(procIn); 
     byos.flush(); 
     procIn.flush(); 

     int ret = exec.waitFor(); 
     System.out.printf("Process exited with value %d", ret); 
    } 

    public static class StreamConsumer implements Runnable { 

     private InputStream input; 

     public StreamConsumer(InputStream input) { 
      this.input = input; 
     } 

     @Override 
     public void run() { 
      BufferedReader reader = new BufferedReader(new InputStreamReader(input)); 
      String line; 
      try { 
       while ((line = reader.readLine()) != null) { 
        System.out.println(line); 
       } 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } finally { 
       try { 
        reader.close(); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 

    } 
} 

这里是输出

Microsoft Windows [Version 6.1.7601] 
Copyright (c) 2009 Microsoft Corporation. All rights reserved. 
** program hangs ** 

为什么程序挂起并执行不进行ping(或打印)?我知道这些流必须被消耗以避免悬挂(我在单独的线程中),但它仍然挂起。我误解了如何将输出流传送到交互式shell或有什么问题?

+0

只是一个猜测,但该方案可以做平,然后更多的投入永远等待(因为它是CMD)。你没有收集任何输出。 –

+0

可能是相关的,但是'StreamConsumer'也不会被使用。 –

回答

1

您必须启动线程消耗的产出:

 new Thread(new StreamConsumer(procOut)).start(); 
     new Thread(new StreamConsumer(procErrOut)).start(); 
+0

我觉得很蠢,已经有一段时间以来,使用线程 –

+0

这解决了这个问题,但仍然有问题,提示'C:\>'不打印,直到输入给出。这是为什么? –

+0

@TuomasToivonen可能是因为输出一次只消耗一行 –