1

我正在编写一个程序,该程序通过使用 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 读取输入?

4

1 回答 1

2

PipedInputStream 的 javadoc 明确表示:

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

(强调我的)

使用 . 将您的输入写入字节数组ByteArrayOutputStream。然后ByteArrayInputStream从这个字节数组构造 a ,并设置System.in为 this ByteArrayInputStream

于 2013-07-28T16:24:20.463 回答