2016-09-30 20 views
1

我有一個程序用ProcessBuilder創建一個進程並執行一個外部程序(.jar)。外部進程應該從標準輸入接收一個字符串,將它們的字符轉換爲較小或大寫,並通過標準輸出發送轉換後的字符串。主進程從鍵盤讀取字符串,使用流將其發送到外部進程並打印外部進程的輸出。但是當我運行主程序時,它似乎陷入了試圖從其stdin讀取數據的外部進程中。 我該如何解決這個問題,有什麼建議?還有另一種方法來完成這個任務(發送String作爲執行外部程序的命令的參數),但我需要使用流來完成。進程之間的Java I/O:外部進程如何從主進程讀取數據?

這裏是主程序代碼:

public static void main(String[] args) throws IOException { 
    String str = JOptionPane.showInputDialog("Insert a String"); 

    String[] cmd = {"java", "-jar", 
    "ejecutable/Transformador2.jar"}; 

    Process process = new ProcessBuilder(cmd).start(); 
    InputStream is = process.getInputStream(); 
    InputStreamReader isr = new InputStreamReader(is); 
    BufferedReader br = new BufferedReader(isr); 

    OutputStream os = process.getOutputStream(); 
    OutputStreamWriter osw = new OutputStreamWriter(os); 
    BufferedWriter bw = new BufferedWriter(osw); 

    bw.write(str); 

    String line; 
    while ((line = br.readLine()) != null) { 
     System.out.println(line); 
    } 
} 

這裏是外部程序的代碼:

public static void main(String[] args) throws IOException { 
    String str, strConv=""; 
    BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); 
    char c; 

    str = input.readLine(); 

    for (int i=0; i<str.length(); i++) { 

     c = str.charAt(i); 

     if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { 
      if (c == Character.toUpperCase(c)) 
       strConv += Character.toLowerCase(c); 
      else if (c == Character.toLowerCase(c)) 
       strConv += Character.toUpperCase(c); 
     } 

    } 

    System.out.print(strConv); 

} 

在此先感謝。

+0

我無法確定這一點,但有可能當您檢查輸出是否爲空時,其他進程尚未打印出任何* yet *,因爲尚未準備好,但原始程序已退出因爲while循環結束。再次,這只是一個瘋狂的猜測。 –

+0

您必須創建一個線程來發送輸入,或者創建一個線程來讀取輸出。沒有創建線程就沒有辦法做到這一點。 – VGR

+0

[這篇文章](http://stackoverflow.com/questions/18903549/writing-to-inputstream-of-a-java-process)可能會有用。 –

回答

0

已解決:在將字符串發送到外部進程之後,需要關閉輸出流。

bw.write(str); 
bw.close(); 
0

確切地說,您需要bw.flush()將數據從緩衝區推送到基礎流。 bw.close()隱式刷新緩衝區。這就是它工作的原因。

+0

這是很好的知道,雖然如果我只用bw.flush()語句嘗試,代碼不起作用。所以我們可以說沖洗後關閉緩衝區也是必要的。感謝你的回答。 – NetrunnerX

+0

您應該始終關閉流以防止資源泄漏。關閉刷新流。在這種情況下,你使用'BufferedReader'來輸入讀取區域。所以,直到數據量不會溢出輸入緩衝區,readLLine會一直停止,或者檢測到行結束符字符,或者直到流關閉 - 這是一個信號,表示沒有更多的數據會來,因此緩衝區可以被emtpied和它的值由'readLine'返回。如果你發送大量的數據,它也可以在不關閉流的情況下工作。 *默認緩衝區大小爲8192個字符* – Antoniossss