如何写“按下回车键”流?

发布于 2024-10-16 14:23:42 字数 1041 浏览 2 评论 0原文

抱歉这个听起来很奇怪的标题...

我有以下情况:我希望我的 Java 程序与外部控制台交互。为了将各个命令“发送”到该控制台,我需要模拟普通控制台上的“按下输入键”。为了澄清我想要什么,假设 mysql 没有其他 API,我需要通过控制台进行交互。虽然这不是我的实际问题,但它已经足够接近了。

我有以下代码:

        String command = "/usr/local/mysql/bin/mysql";
        Process child = Runtime.getRuntime().exec(command);

        StreamGobbler gobbler = new StreamGobbler(child.getInputStream());
        gobbler.start();

        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(child.getOutputStream()));
        out.write("help");
        // here enter key needs to be pressed
        out.flush();
        // out.close();

如果执行了对 out.close() 的调用,则一切正常。但当然,这样我只能发送单个命令,这不是我想要的。但如果省略out.close(),则另一个程序永远不会执行该命令。我的猜测是它仍然等待命令“完成”,在普通控制台上可以通过按 Enter 来完成。 out.write(System.getProperty("line.separator"));out.newLine(); (相同)并没有解决问题,也没有out.write("\r\n");out.write((char) 26); (EOF)。

当然,也可能是我做的完全错误(即错误的方法)。然后我将不胜感激指向正确方向的指针...

对此的任何帮助都非常感谢。

Sorry for this odd-sounding title...

I have the following situation: I want my Java program to interact with an external console. In order to "send" the individual commands to that console, I need to simulate what would be an "enter key pressed" on a normal console. To clarify what I want, imagine mysql had no other API and I would need to interact via console. Although this is not my actual problem, it is close enough.

I have the following code:

        String command = "/usr/local/mysql/bin/mysql";
        Process child = Runtime.getRuntime().exec(command);

        StreamGobbler gobbler = new StreamGobbler(child.getInputStream());
        gobbler.start();

        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(child.getOutputStream()));
        out.write("help");
        // here enter key needs to be pressed
        out.flush();
        // out.close();

If the call to out.close() is executed, everything is fine. But of course, this way I can only send a single command, which is not what I want. But if out.close() is omitted, the other program never executes the command. My guess is that it still waits for the command to "finish", which on a normal console would be done by pressing enter. out.write(System.getProperty("line.separator")); and out.newLine(); (which are the same) do not solve the problem, neither does out.write("\r\n"); and out.write((char) 26); (EOF).

Of course, it might be, that I am doing it completely wrong (i.e., wrong approach). Then I would appreciate a pointer into the right direction...

Any help on this highly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

淡水深流 2024-10-23 14:23:42

以下代码在使用 Java 1.6.0_23 的 Windows 7 和使用 Java 1.6.0_22 的 Ubuntu 8.04 上运行良好:

public class Laj {

  private static class ReadingThread extends Thread {
    private final InputStream inputStream;
    private final String name;

    public ReadingThread(InputStream inputStream, String name) {
      this.inputStream = inputStream;
      this.name = name;
    }

    public void run() {
      try {
        BufferedReader in = new BufferedReader(
            new InputStreamReader(inputStream));
        for (String s = in.readLine(); s != null; s = in.readLine()) {
          System.console().writer().println(name + ": " + s);
        }
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }

  public static void main(String[] args) throws Exception {
    String command = "psql -U archadm arch";
    final Process child = Runtime.getRuntime().exec(command);
    new ReadingThread(child.getInputStream(), "out").start();
    new ReadingThread(child.getErrorStream(), "err").start();
    BufferedWriter out = new BufferedWriter(
        new OutputStreamWriter(child.getOutputStream()));
    out.write("\\h");
    out.newLine();
    out.flush();
    out.write("\\q");
    out.newLine();
    out.flush();
  }

}

newLine() 与编写平台行分隔符相同。正如人们所期望的那样,它打印出前面带有“out:”的帮助,然后退出。如果我不发送“\q”,它不会退出(显然)但仍然打印帮助。使用“\r\n”或“\r”而不是平台行分隔符对我来说看起来不是一个好主意,因为此类命令行实用程序通常会检测到它们没有从终端获取输入并假设它采用本机文本格式(认为“psql < script.sql”)。好的软件应该正确检测并接受所有合理的行结尾。

The following code works fine on both Windows 7 using Java 1.6.0_23 and on Ubuntu 8.04 using Java 1.6.0_22:

public class Laj {

  private static class ReadingThread extends Thread {
    private final InputStream inputStream;
    private final String name;

    public ReadingThread(InputStream inputStream, String name) {
      this.inputStream = inputStream;
      this.name = name;
    }

    public void run() {
      try {
        BufferedReader in = new BufferedReader(
            new InputStreamReader(inputStream));
        for (String s = in.readLine(); s != null; s = in.readLine()) {
          System.console().writer().println(name + ": " + s);
        }
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }

  public static void main(String[] args) throws Exception {
    String command = "psql -U archadm arch";
    final Process child = Runtime.getRuntime().exec(command);
    new ReadingThread(child.getInputStream(), "out").start();
    new ReadingThread(child.getErrorStream(), "err").start();
    BufferedWriter out = new BufferedWriter(
        new OutputStreamWriter(child.getOutputStream()));
    out.write("\\h");
    out.newLine();
    out.flush();
    out.write("\\q");
    out.newLine();
    out.flush();
  }

}

newLine() is the same as writing the platform line separator. As one would expect, it prints help preceded with "out: ", then exits. If I don't send "\q", it doesn't exit (obviously) but still prints help. Using "\r\n" or "\r" instead of the platform line separator doesn't look like a good idea to me, because such command-line utilities will usually detect that they don't get input from the terminal and assume it is in the native text format (think "psql < script.sql"). Good software should properly detect and accept all reasonable line endings though.

梦里梦着梦中梦 2024-10-23 14:23:42

out.write((char) 13) 怎么样?请参阅这篇维基百科文章。我没有足够的代码来为您测试这一点。

What about out.write((char) 13)? See this Wikipedia article. I don't have enough code to test this for you.

秋日私语 2024-10-23 14:23:42

您可能还想尝试查看此 API

http:// /download.oracle.com/javase/6/docs/api/java/io/Console.html

根据我的经验,除了从 Process API 运行一个进程之外,我从未尝试过执行任何其他操作。看起来您想要输入多个命令,我认为这个 API 可以让您做到这一点。

编辑:找到了一个教程来进一步帮助您。
http://download.oracle.com/javase/tutorial/essential/io /cl.html

希望这有帮助,

You also might want to try looking at this API

http://download.oracle.com/javase/6/docs/api/java/io/Console.html

From my experience, I've never tried doing anything more than running one process from the Process API. It seems like you want to enter multiple commands I think this API might let you do that.

EDIT: Found a tutorial on it to help you further.
http://download.oracle.com/javase/tutorial/essential/io/cl.html

Hope this helps,

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文