gpt4 book ai didi

java - 读取守护进程的输入流导致程序卡住

转载 作者:行者123 更新时间:2023-12-02 01:03:53 25 4
gpt4 key购买 nike

出于测试目的,我需要从命令行启动守护进程,并且需要读取该进程的输出(输入流、错误流)。当我尝试读取进程输出时,它卡在 bufferedReader.readLine()

    String command = "start server";
String output = "";
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c");
pb.directory(new File("C:\\tmp"));
Process proc = null;
try {
proc = pb.start();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));
writer.write(command, 0, command.length());
writer.newLine();
writer.close();
proc.waitFor(20, TimeUnit.SECONDS);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
String line;
while ((line = stdInput.readLine()) != null) {
output = output + line + "\n";
System.out.println(output);
}
while ((line = stdError.readLine()) != null)
output = output + line + "\n";
ByteArrayOutputStream opStream = new ByteArrayOutputStream();
opStream.writeTo(proc.getOutputStream());
String stdOutput = new String(opStream.toByteArray());
output = output + stdOutput;
} catch (Exception e) {
System.out.println("Exception while running command. " + e.getMessage());
} finally {
if (proc != null)
proc.destroyForcibly();
System.out.println(output);
}

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

最佳答案

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

如果你想使用java io,一种方法是从两个单独的线程读取两个流。 (您需要分别排出两个流,因为每个流都有一个固定大小的缓冲区。如果其中一个缓冲区填满,整个过程就会卡住,直到它被排出)

类似于:

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();

}

关于java - 读取守护进程的输入流导致程序卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57748569/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com