2013-07-27 41 views
1

我正在編寫一個程序,該程序通過使用Class和Method類來調用main方法來執行另一個Java程序。這個其他程序然後嘗試從System.in中讀取。爲了將參數傳遞給程序,我將System.in設置爲連接到PipedOutputStream的PipedInputStream。我將其他程序請求的參數傳遞給PipedOutputStream,然後調用main方法。
但是,只要該方法被調用,程序就會死鎖。這是爲什麼?理論上,其他程序應該可以訪問參數,因爲它們已經在PipedInputStream中可用。
我無法改變其他程序讀取輸入的方式,所以此解決方案無法工作。PipedInputStream沒有被內部調用的Java程序讀取

這裏一些示例代碼:
其中I分配的部分中的PipedStreams

PipedInputStream inputStream = new PipedInputStream(); 
PipedStringOutputStream stringStream = new PipedStringOutputStream(); // custom class 

try { 
    stringStream.connect(inputStream); 
} catch (IOException e2) { 
    e2.printStackTrace(); 
} 
System.setIn(inputStream); 

的部分,其中我調用的方法:

Class main = classes.get(className); 
try { 
    Method m = main.getMethod("main", String[].class); 

    // write all parameters to System.in 
    String[] params = getParams(); // custom method, works (params is not empty) 
    for(int j = 0; j < params.length; j++) { 
     stringStream.write(params[j]); 
    } 

    params = null; 
    m.invoke(null, (Object) params); // this is were the program stops 
} catch(Exception e) {} 

的PipedStringOutputStream類:

public class PipedStringOutputStream extends PipedOutputStream { 

    public void write(String output) throws IOException { 
     this.write((output + "\n").getBytes()); 
     flush(); 
    } 
} 

我從System讀取的測試程序.in:

public static void main(String[] args) { 
    Scanner sc = new Scanner(System.in); 
    while(sc.hasNext()) { 
     System.out.println(sc.nextLine()); 
    } 
} 

那麼是什麼問題?我是否必須在線程中啓動Streams?爲什麼其他程序不能讀取來自PipedInputStream的輸入?

+1

(1)這裏沒有任何代碼可以讀取任何東西,更不用說管道了。 (2)由於您已經直接將參數傳遞給main(),爲什麼管道? (3)這裏有什麼問題? – EJP

+0

你的主要方法在做什麼?也顯示它的代碼。 – Mac

+0

@EJP:1)我添加了一些示例代碼,從System.in中讀取 2)我沒有直接將參數傳遞給main(),params在此時爲null。另一個程序將從System.in中讀取,所以我必須以這種方式傳遞參數。 3)問題是我如何將參數傳遞給System.in,以便其他程序可以讀取它們。假設管道是正確的一步,我想知道我的代碼中有什麼問題。 – Cecilya

回答

2

的PipedInputStream的的JavaDoc明確地說:

典型地,數據被從一個對象的PipedInputStream由一個線程讀取,並且數據被從其他線程寫入相應的PipedOutputStream。 不建議嘗試使用來自單個線程的兩個對象,因爲它可能會使線程發生死鎖。

(重點煤礦)

寫您的輸入使用ByteArrayOutputStream的字節數組。然後從這個字節數組構造一個ByteArrayInputStream,並將System.in設置爲這個ByteArrayInputStream

+0

謝謝!這工作正常,如果我調用另一個程序的主要方法作爲一個普通的方法調用,但是當我通過invoke()調用它時,它似乎無法從ByteArrayInputStream讀取,即使正確的字節有讀取。 Scanner的hasNext()方法總是返回false。爲什麼會這樣呢? – Cecilya

+0

直接調用使用反射的方法不應該改變任何東西。使用hashNextLine()來測試是否有下一行。不是hasNext()。 –

+0

現在,它的工作。我對Java的按值調用系統有點困難,這就是爲什麼System.in沒有設置爲正確的流。 – Cecilya

相關問題