-1

作为背景,我在 Heroku 上部署了一个基于 Java 的 Discord 机器人,使用 1 个免费的 worker dyno。我需要运行一个 .exe 文件(stockfish 12 可执行文件),将输入传递给它并处理它的输出。我正在使用 Java RunTime 来创建这个进程,但是当我尝试使用 flush() 方法向它发送输入时,会抛出损坏的管道错误。我假设 Heroku 必须以某种方式关闭输入/输出流,因为此代码在本地运行良好。Heroku 对创建子进程有限制吗?

应用程序 [worker.1]:chess.player.ai.stockfish.exception.StockfishEngineException:java.io.IOException:断管应用程序 [worker.1]:在 chess.player.ai.stockfish.engine.UCIEngine.sendCommand(UCIEngine .java:39) app[worker.1]:在 chess.player.ai.stockfish.engine.UCIEngine.passOption(UCIEngine.java:77) app[worker.1]:在 chess.player.ai.stockfish.engine .UCIEngine.(UCIEngine.java:23) app[worker.1]: at chess.player.ai.stockfish.engine.Stockfish.(Stockfish.java:13) app[worker.1]: at chess.player.ai .stockfish.StockFishClient.(StockFishClient.java:21) app[worker.1]: at chess.player.ai.stockfish.StockFishClient$Builder.build(StockFishClient.java:80)

编辑:我试图通过对单个命令进行硬编码来简化程序,但它仍然无法通过 writer.flush() 行。什么都没有打印。

Process process = new ProcessBuilder().command("bin/stockfish_20090216_x64_bmi2.exe").start();

StringBuilder output = new StringBuilder();
BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
writer.write("position fen rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" + "\n");
writer.write("go movetime 1000");
writer.flush();

String line;
while ((line = input.readLine()) != null) {
    output.append(line + "\n");
}

int exitVal = process.waitFor();
if (exitVal == 0) {
    System.out.println("success");
    System.out.println(output.toString());
}
else {
    System.out.println("error");
}
4

2 回答 2

0

output流自行关闭。当您运行命令时,创建一个新进程,否则此命令必须阻止流并等待输入。

推荐ProcessBuilder,更容易配置:

new ProcessBuilder().command("cmd.exe", "/c", "command")
                    .directory(new File(path))
                    .redirectInput(new File(path, "input.txt"))
                    .redirectOutput(new File(path, "output.txt"))
                    .redirectError(new File(path, "runtime_error.txt"))
                    .start()
                    .waitFor();
于 2020-10-08T01:55:23.610 回答
0

原来我使用了错误的二进制文件。Stockfish 二进制文件有许多不同的格式,显然适用于我本地的那种格式不适用于 Heroku。

于 2020-10-09T00:35:08.477 回答