内部调用Java程序不会读取PipedInputStream

时间:2013-07-27 11:56:09

标签: java stream

我正在编写一个程序,通过使用Class和Method类来调用main方法来执行另一个Java程序。然后,此其他程序尝试从System.in读取。为了将参数传递给程序,我将System.in设置为连接到PipedOutputStream的PipedInputStream。我将其他程序请求的参数传递给PipedOutputStream,然后调用main方法 但是,只要调用该方法,程序就会死锁。这是为什么?从理论上讲,另一个程序应该可以访问参数,因为它们已经在PipedInputStream中可用了。
我无法改变其他程序读取输入的方式,因此该解决方案无效。

这里有一些示例代码:
我指定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 个答案:

答案 0 :(得分:2)

PipedInputStream的javadoc明确地说:

  

通常,一个线程从PipedInputStream对象读取数据,而其他线程将数据写入相应的PipedOutputStream。 建议不要尝试使用单个线程中的两个对象,因为它可能使线程死锁

(强调我的)

使用ByteArrayOutputStream将输入写入字节数组。然后从此字节数组构造ByteArrayInputStream,并将System.in设置为此ByteArrayInputStream