2017-02-20 156 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可能是因爲輸出一次只消耗一行 –