Java Process:在单个线程

时间:2016-10-08 10:49:52

标签: java process runtime.exec

假设我已经在Java中启动了一个子进程,可能会写入stdout和stderr:

Process subprocess = Runtime.getRuntime().exec(…);

我想阅读它的所有标准记和stderr;或者只是忽略它们。

  1. 如果我喜欢这样:

    readAllFrom(subprocess.getInputStream()); //stdout is getInputStream, weird!
    readAllFrom(subprocess.getErrorStream()); //stderr
    

    ...如果子进程首先尝试将数据输出到stderr并因此在那时阻塞,它就会卡住。

    如果我做这样的事情:

    while (…) {
        readLineFrom(subprocess.getInputStream());
        readLineFrom(subprocess.getErrorStream());
    }
    
    实际上,风险似乎是相同的。

  2. 如果我喜欢这样:

    while (…) {
        nonblockingReadFrom(subprocess.getInputStream());
        nonblockingReadFrom(subprocess.getOutputStream());
    }
    

    其中nonblockingReadFrom可以是:

    … nonblockingReadFrom(InputStream stream) {
        byte[] buffer = new byte[…];
        stream.read(buffer, 0, Math.min(stream.available(), buffer.length));
        …
    }
    

    ...如果子流程输出数据有一些暂停,它将使无用的100%-CPU负载。

  3. 当然,我可以创建单独的线程。像这里的东西(12)。但我的问题是在同一个线程中做所有事情。可能需要select system call的Java接口之类的东西。

  4. 所以,问题是:是否有可能在Java中正确处理java.lang.Process类型的子进程的stdout和stderr而不使用其他线程或临时文件?

1 个答案:

答案 0 :(得分:1)

不,您不能仅从SelectableChannel返回的InputStream创建Process,这是Java api限制AFAICT。