2013-06-24 70 views
2

我有以下類文件。這將啓動一個命令提示符並打印響應。奇怪的是在第一次打印後,即後面的dir不打印。請指教。命令提示符中的Java問題命令

import java.io.*; 
public class JavaApplication14 { 
static Process p; 

public static void main(String[] args) { 
    try { 
     String line; 

     p = Runtime.getRuntime().exec("cmd.exe"); 
     OutputStream stdin = p.getOutputStream(); 
     InputStream stderr = p.getErrorStream(); 
     InputStream stdout = p.getInputStream(); 

     BufferedReader reader = new BufferedReader(new InputStreamReader(stdout)); 
     BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin)); 

     String input = "dir"; 
     input += "\n"; 
     writer.write(input); 
     writer.flush(); 



     while ((line = reader.readLine()) != null) { 
      System.out.println("Stdout: " + line); 
     } 
     input = "cd.."; 
     input += "\n"; 
     writer.write(input); 
     writer.flush(); 
     input = "dir"; 
     input += "\n"; 
     writer.write(input); 
     writer.close(); 

     while ((line = reader.readLine()) != null) { 
      System.out.println("Stdout: " + line); 
     } 
    } catch (IOException ex) { 
     Logger.getLogger(JavaApplication14.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 
} 
+0

在代碼中沒有循環來重複'dir'ing。你使用'線'爲什麼?它似乎只是簡單閱讀,但沒有在任何地方使用。 – allprog

回答

4

你的(第一)while()循環永遠不會終止:

while ((line = reader.readLine()) != null) { 
    System.out.println("Stdout: " + line); 
} 

readLine()回報null當流被關閉,但因爲你的子進程仍在運行,流永遠不會被關閉。

要解決這個問題,您可以將讀取部件移動到單獨的線程中(這需要額外的同步),或者更簡單的解決方案是查看是否讀取了特定的行內容,例如,如果命令行提示符是通過印刷cmd.exe

while (!(line = reader.readLine()).startsWith("C:\\")) { 
    System.out.println("Stdout: " + line); 
} 

這應該針對具體應用的情況下工作,可能足以去做一些學習 - 真正的應用程序,你可能想看看進入Apache Commons Exec項目。

+0

那它應該是什麼? – user903772

+1

直到有更多的輸入時,總會有'readLine()'阻塞的危險。 –

+0

@MarkoTopolnik就我個人而言,我會使用線程方法,但正如您所寫,「...這是Java中的一個痛點......」 –

2

您正嘗試使用同步I/O操作從一個線程完成基本異步工作。你的方法肯定會失敗。

具體而言,readLine()會阻塞,直到有整行被讀取,或者直到底層流被關閉。

你必須編寫更多的代碼,涉及線程才能完成這項工作。這在Java中是一個痛點。

您也可以使用ProcessBuilder,特別是其redirectOutput方法與參數值INHERIT,使子繼承你的主要過程的stdout。在這種情況下,您將沒有機會分析Java中的子進程輸出。

+1

+1 [新ProcessBuilder](http:// docs。 oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html) – linski