Java 读取守护进程的inputstream导致程序卡住

Java 读取守护进程的inputstream导致程序卡住,java,inputstream,Java,Inputstream,出于测试目的,我需要从命令行启动一个守护进程,并读取进程的输出(输入流、错误流)。当我试图读取进程输出时,它被bufferedReader.readLine()卡住了 我可以为缓冲读取器使用超时,这样程序就不会卡住。 调用守护进程并读取其输出的最佳方法是什么?标准java io正在阻塞。您可能可以使用新的io(nio),但它还有其他缺点(使用起来很复杂) 如果要使用JavaIO,一种方法是从两个单独的线程读取两个流。(您需要分别排空两个流,因为每个流都有一个固定大小的缓冲区。如果其中一个缓冲区填

出于测试目的,我需要从命令行启动一个守护进程,并读取进程的输出(输入流、错误流)。当我试图读取进程输出时,它被bufferedReader.readLine()卡住了

我可以为缓冲读取器使用超时,这样程序就不会卡住。
调用守护进程并读取其输出的最佳方法是什么?

标准java io正在阻塞。您可能可以使用新的io(nio),但它还有其他缺点(使用起来很复杂)

如果要使用JavaIO,一种方法是从两个单独的线程读取两个流。(您需要分别排空两个流,因为每个流都有一个固定大小的缓冲区。如果其中一个缓冲区填满,整个过程将冻结,直到排空为止)

比如:

private static class StreamGobbler implements Runnable {
    private final InputStream stream;

    private final ByteArrayOutputStream output;

    public StreamGobbler(InputStream stream) {
        this.stream = stream;
        output = new ByteArrayOutputStream();
    }

    @Override
    public void run() {
        try {
            int read;
            while ((read = stream.read()) >= 0) {
                output.write(read);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

{
    StreamGobbler stdin = new StreamGobbler(proc.getInputStream());
    StreamGobbler stdout = new StreamGobbler(proc.getErrorStream());
    Executor executor = Exectors.newFixedThreadPool(2);
    executor.submit(stdin);
    executor.submit(stdout);

    // do io for process
    // wait for process to finish
    // shutdown executorservice

    byte[] stdinBytes = stdin.output.toByteArray();
    byte[] stderrBytes = stderr.output.toByteArray();

}

无法复制:由于
cmd.exe/c
不执行任何操作,会立即返回,因此发送的命令将被忽略,并且不会生成任何输出,因此Java代码在打印1个空行后立即结束,不会出错。好奇的是,
opStream
的目的是什么?您可以通过tearrayoutputstream创建一个
,然后将空内容写入进程。重点是什么?什么也不写?向已经完成的流程写入的过程?然后从仍然为空的
opStream
内容创建一个字符串。再说一遍:为什么?!?谢谢你的建议。你能解释一下我如何使用nio做同样的事情吗?
private static class StreamGobbler implements Runnable {
    private final InputStream stream;

    private final ByteArrayOutputStream output;

    public StreamGobbler(InputStream stream) {
        this.stream = stream;
        output = new ByteArrayOutputStream();
    }

    @Override
    public void run() {
        try {
            int read;
            while ((read = stream.read()) >= 0) {
                output.write(read);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

{
    StreamGobbler stdin = new StreamGobbler(proc.getInputStream());
    StreamGobbler stdout = new StreamGobbler(proc.getErrorStream());
    Executor executor = Exectors.newFixedThreadPool(2);
    executor.submit(stdin);
    executor.submit(stdout);

    // do io for process
    // wait for process to finish
    // shutdown executorservice

    byte[] stdinBytes = stdin.output.toByteArray();
    byte[] stderrBytes = stderr.output.toByteArray();

}