首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java ProcessBuilder限制

Java ProcessBuilder限制
EN

Stack Overflow用户
提问于 2015-07-02 17:53:02
回答 1查看 2.2K关注 0票数 1

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

代码语言:javascript
运行
复制
new ProcessBuilder(new String[]{"/bin/bash", "-c", "./start_server"}).start();

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-02 19:06:21

您必须读取输出(即使只是丢弃它),stdout和stderr都是如此。否则,输出缓冲区将被填满,从而导致奇怪的行为。

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

代码语言:javascript
运行
复制
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();

但是,如果必须使用Java1.6或更低版本,则必须使用自己的版本。这是我在我的项目中使用的:

代码语言:javascript
运行
复制
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();
    }
}

你可以这样称呼它:

代码语言:javascript
运行
复制
Process process = new ProcessBuilder("/bin/bash", "-c", "./start_server")
                      .start();

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

或者像这样:

代码语言:javascript
运行
复制
Process process = new ProcessBuilder("/bin/bash", "-c", "./start_server")
                      .redirectErrorStream(true)
                      .start();

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

请注意,ProcessBuilder构造函数采用的是String... (varargs),而不是String[] (尽管您可以手动创建和传递String[])。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31191391

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档