当从cmd行执行一些命令(比如说'x')时,我收到以下消息: “....按任意键继续 。 。 。”。所以它等待用户输入解锁。
但是当我从java执行相同的命令('x')时:
Process p = Runtime.getRuntime().exec(cmd, null, cmdDir);
// here it blocks and cannot use outputstream to write somnething
p.getOutputStream().write(..);
代码块......
我试着在进程的输出流中写入一些东西,但是我怎么能这样做,代码永远不会到达那一行呢?
答案 0 :(得分:2)
我认为(虽然不能肯定)你在谈论Windows而不是Unix?
如果是这样,命令行进程可能实际上没有等待stdin
上的按键(或输入),而是等同于旧的DOS kbhit()
函数。
AFAIK没有办法让这个功能相信键盘已被按下而没有按下键。
要测试此理论,请创建一个文本文件“input.txt”,其中包含一些空行,然后运行:
foo.exe < input.txt
这将显示您的程序是在等待stdin
还是等待其他内容。
答案 1 :(得分:2)
您应该同时阅读子流程的输出和错误流。这些流的缓冲区大小是有限的。如果其中一个缓冲区已满,则子进程将阻塞。我认为这就是你的情况。
答案 2 :(得分:1)
我认为在Java中执行外部应用程序的推荐光线是使用ProcessBuilder。代码看起来像
//Launch the program
ArrayList<String> command = new ArrayList<String>();
command.add(_program);
command.add(param1);
...
command.add(param1);
ProcessBuilder builder = new ProcessBuilder(command);
//Redirect error stream to output stream
builder.redirectErrorStream(true);
Process process = null;
BufferedReader br = null;
try{
process = builder.start();
InputStream is = process.getInputStream();
br = new BufferedReader( new InputStreamReader(is));
String line;
while ((line = br.readLine()) != null) {
log.add(line);
}
}catch (IOException e){
e.printStackTrace();
}finally{
try{
br.close();
}catch (IOException e){
e.printStackTrace();
}
}
流程对象有一个get [输入/输出/错误]流,可用于与程序交互。
答案 3 :(得分:0)
程序无法继续,因为它被阻止,期望用户输入。
一个选项是在单独的线程中启动外部进程,或者使用共享进程p的线程以便能够写入其流。
答案 4 :(得分:0)
我在this stackoverflow question写了一个命令行执行的答案。
你可能需要回复,因为你的回答会有点棘手。
在你的情况下,我可能需要给输入流gobbler类似回复频道:
StreamGobbler outputGobbler = new StreamGobbler(
proc.getInputStream(), "OUTPUT",
proc.getOutputStream());
并使其匹配模式并回复给定的输入流。
while ((line = br.readLine()) != null) {
System.out.println(type + ">" + line);
if (line.contains(PRESS_KEY_CONTINUE) {
ostream.write("y".getBytes("US-ASCII"));
System.out.println("< y");
}
}
希望这有帮助。
答案 5 :(得分:0)
所以这是我对这个问题的解决方法,灵感来自Alnitak的建议: 像这样运行命令:
Process p = Runtime.getRuntime().exec(cmd + " < c:\\someTextFile.txt", null, cmdDir);
...
int errCode = p.waitFor();
...
'someTextFile.txt'可以编程方式创建到临时目录中然后删除。
答案 6 :(得分:0)
使用PrintWriter模拟一些输入:
Process p = Runtime.getRuntime().exec(cmd, null, cmdDir);
//consume the proces's input stream
........
// deblock
OutputStream outputStream = p.getOutputStream();
PrintWriter pw = new PrintWriter(outputStream);
pw.write("ok");
pw.flush();
int errCode = p.waitFor();
答案 7 :(得分:0)
我有同样的问题,我找到了解决方案。它不是最优雅的,但它确实有效。
1 - 当您执行该过程时,您将从该过程获取inputStream 2 - 然后你创建一个循环接收提示中显示的消息(如果有的话) 3 - 当你看到你从“提示”得到“按一个键继续”,或者其他什么时,你就结束了过程
// Creates the runtime and calls the command
Process proc = Runtime.getRuntime().exec(Destino);
// Get the proccess inputStream
InputStream ips = proc.getInputStream();
String output = "";
int c = 0;
// Read the output of the pro
while ((c = ips.read()) != -1
&& !output.contains("Press any key to continue")) {
output = output + (char)c;
}
// Destroy the proccess when you get the desired message
proc.destroy();