java 如何将“按下输入键”写入流?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4935903/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 08:40:58  来源:igfitidea点击:

How to write "enter key pressed" to a stream?

javainterfaceprocess

提问by roesslerj

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.

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

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).

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

对此高度赞赏的任何帮助。

回答by Sergei Tachenov

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:

以下代码在使用 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() 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.

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

回答by rancidfishbreath

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

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

回答by jluzwick

You also might want to try looking at this API

您可能还想尝试查看此 API

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

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.

根据我的经验,除了从 Process API 运行一个进程之外,我从未尝试过做任何其他事情。似乎您想输入多个命令,我认为此 API 可能会让您这样做。

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

编辑:找到有关它的教程以进一步帮助您。 http://download.oracle.com/javase/tutorial/essential/io/cl.html

Hope this helps,

希望这可以帮助,