如何写“按下回车键”流?
抱歉这个听起来很奇怪的标题...
我有以下情况:我希望我的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
以下代码在使用 Java 1.6.0_23 的 Windows 7 和使用 Java 1.6.0_22 的 Ubuntu 8.04 上运行良好:
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:
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.
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.您可能还想尝试查看此 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,