【问题标题】:Java: Communicating with a command line applicationJava:与命令行应用程序通信
【发布时间】:2023-12-12 05:45:01
【问题描述】:

我想用 Java 编写一个国际象棋 GUI。用户可以输入一个动作,然后我希望程序做出一个动作。因此,我将使用 UCI(通用国际象棋接口)。 UCI 是一个终端/命令行应用程序(我使用的是 Mac OS X 和终端),它计算一个位置的最佳移动。现在我需要做的是读写这个终端应用程序。

例如: 我想要某个位置的最佳移动,所以我输入: “go”(计算最佳移动)

假设我得到了这个答案: “e2e4”(表示将棋子(即国际象棋中的棋子)从 e2 格移动到 e4 格)

现在我需要阅读“e2e4”,然后询问用户他的下一步行动。所以我有点需要一直循环这些步骤,直到有一个将死: 1. 要求搬家 2. 计算最佳响应

我已经看到很多其他 * 问题都在问同样的问题:如何运行命令并在命令行/终端中获取其输出。但是所有答案都只使用一个命令,例如runtime.exec("ls"); 但这只是一个命令。我想要的是输入一个命令,获取响应,执行另一个命令等等,所以基本上我需要与 Mac OSX 的终端应用程序通信(交替输入和输出)。我如何在 Java 中做到这一点?

【问题讨论】:

    标签: java macos io terminal communication


    【解决方案1】:

    您可以执行运行国际象棋程序的命令,然后检查命令的输出以获得最佳移动(使用Process)。

    例如:

    String move = null;
    Process process = Runtime.getRuntime().exec("go");
    BufferedReader reader = new BufferedReader(new InputStreamReader(process.getOutputStream()));
    move = reader.readLine();
    // 'move'  now holds a reference to the chess program's output, or null if there was none.
    

    【讨论】:

      【解决方案2】:

      只需查找 Runtime.exec() 的返回类型。它返回一个java.lang.Process

      它提供了两种输入输出流的方法:getOutputStream() 和 getInputStream()

      您可以读取和写入打开的进程,例如。使用 BufferedReaders / BufferedWriters。

      例如:(另见https://*.com/a/14745245/2358582

      import java.io.*;
      
      public class c {
          public static void main(String[] args) throws Exception{
              Process p = Runtime.getRuntime().exec("cmd");
              BufferedReader inp = new BufferedReader(new InputStreamReader(p.getInputStream()));
              BufferedWriter out = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
      
              //communication
              setUpStreamGobbler(p.getInputStream(), System.out);
              out.write("cmd\n");
              out.flush();
          }
      
          public static void setUpStreamGobbler(final InputStream is, final PrintStream ps) {
              final InputStreamReader streamReader = new InputStreamReader(is);
              new Thread(new Runnable() {
                  public void run() {
                      BufferedReader br = new BufferedReader(streamReader);
                      String line = null;
                      try {
                          while ((line = br.readLine()) != null) {
                              ps.println("process stream: " + line);
                          }
                      } catch (IOException e) {
                          e.printStackTrace();
                      } finally {
                          try {
                              br.close();
                          } catch (IOException e) {
                              e.printStackTrace();
                          }
                      }
                  }
              }).start();
          }
      }
      

      输出:

      process stream: Microsoft Windows [Version 6.1.7601]
      process stream: Copyright (c) 2009 Microsoft Corporation. Alle Rechte vorbehalte
      n.
      process stream:
      process stream: P:\Java\ExcecuteFile>cmd
      process stream: Microsoft Windows [Version 6.1.7601]
      process stream: Copyright (c) 2009 Microsoft Corporation. Alle Rechte vorbehalte
      n.
      process stream:
      

      【讨论】:

      • 这不起作用,Intellij IDEA 标记了这个错误:错误:(16, 30) java: no suitable constructor found for BufferedReader(java.io.OutputStreamWriter) 构造函数 java.io.BufferedReader.BufferedReader (java.io.Reader)不适用(实参java.io.OutputStreamWriter不能通过方法调用转换为java.io.Reader)构造函数java.io.BufferedReader.BufferedReader(java.io.Reader,int)是不适用(实际和形式参数列表的长度不同)
      • 我发现错误:代码中应该是BufferedWriter
      • 现在一切正常,如何将结果输出到控制台? (使用 System.out.println()?)
      • 发帖前一定要三思而后行 :) 是的,你可以用 System.out.println(buf); 输出它
      • 没有,但是不行,out.write("command") 没有执行
      【解决方案3】:

      我相信这个问题可能会对您有所帮助: I asked something similar, 我希望这能回答你的问题

      【讨论】:

        最近更新 更多