gpt4 book ai didi

Java ProcessBuilder 限制

转载 作者:行者123 更新时间:2023-11-30 03:21:36 26 4
gpt4 key购买 nike

我有一个通过套接字连接到本地服务器的 Java 程序,如果 Java 检测到它没有运行,我希望不必手动启动服务器。因此,如果 Java 未连接到服务器,那么我使用 ProcessBuilder 来启动它:

new ProcessBuilder(new String[]{"/bin/bash", "-c", "./start_server"}).start();

这会启动服务器,并运行大约 4 分钟,直到服务器进程没有响应。有趣的是,如果我发送更多命令,发生这种情况所需的时间就会更少。我想知道我是否遇到了 ProcessBuilder 的限制,可能使用了太多内存。我在服务器端打印与服务器的通信,因为这是从 ProcessBuilder 调用的,我假设它被定向到其他地方,问题就在这里。

最佳答案

您必须读取输出(即使您只是将其丢弃),包括 stdout 和 stderr。否则输出缓冲区将填满,导致奇怪的行为。

最简单的方法是重定向到位存储桶(假设 Java 1.7+):

File bitbucket;

if (isWindows()) {
bitbucket = new File("NUL");
} else {
bitbucket = new File("/dev/null");
}

Process process = new ProcessBuilder("/bin/bash", "-c", "./start_server")
.redirectOutput(ProcessBuilder.Redirect.appendTo(bitbucket))
.redirectError(ProcessBuilder.Redirect.appendTo(bitbucket))
.start();

但是如果您必须使用 Java 1.6 或更低版本,则必须自行开发。这是我在项目中使用的:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class StreamConsumer
{
private final InputStream stream;

private StreamConsumer(InputStream is)
{
this.stream = is;
}

private Runnable worker()
{
return new Worker();
}

private class Worker implements Runnable
{
@Override
public void run()
{
try (BufferedReader br = new BufferedReader(new InputStreamReader(stream))) {
while (br.readLine() != null) {
/* No one cares */
}
} catch (IOException ioe) {
/* No one cares */
}
}
}

public static void consume(InputStream stream, String label)
{
Thread t = new Thread(new StreamConsumer(stream).worker(), label);
t.setPriority(Thread.MIN_PRIORITY);
t.start();
}
}

你可以这样调用它:

Process process = new ProcessBuilder("/bin/bash", "-c", "./start_server")
.start();

StreamConsumer.consume(process.getInputStream(), "STDOUT");
StreamConsumer.consume(process.getErrorStream(), "STDERR");

或者像这样:

Process process = new ProcessBuilder("/bin/bash", "-c", "./start_server")
.redirectErrorStream(true)
.start();

StreamConsumer.consume(process.getInputStream(), "STDOUT/STDERR");

请注意,ProcessBuilder 构造函数采用 String...(可变参数),而不是 String[](尽管您可以创建和如果需要,请手动传递 String[])

关于Java ProcessBuilder 限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31191391/

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