带有 .exe 的 Java 输入/输出流
我想做的是,用Java启动一个.exe控制台程序,并使用Java从控制台窗口操作输入和输出流。我知道我可以从应用程序获取输入和输出流,这就是我目前正在做的事情:
try {
process = Runtime.getRuntime().exec("C:\\Users\\Owner\\Documents\\testApp\\console.exe");
} catch (IOException e1) {
e1.printStackTrace();
return;
}
stdin = process.getOutputStream();
stdout = process.getInputStream();
然后,我可以使用 BufferedReader 来显示 .exe 通常显示的输出,但是我不知道如何传递从 Java 应用程序控制台程序输入到实际的 .exe 输入流。我需要一些关于如何执行此操作的帮助。
编辑: 好的,我现在有了这个,它可以同时工作;但是,我似乎无法获得与从 Java 控制台窗口获取的任何输入相关的任何输出。
new Thread(new Runnable() {
public void run() {
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
try {
while ((line = br.readLine()) != null) {
System.out.println("[OUT] " + line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
public void run() {
try {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = System.in.read(buffer)) != -1) {
for(int i = 0; i < buffer.length; i++) {
int intValue = new Byte(buffer[i]).intValue();
if (intValue == 0) {
bytesRead = i;
break;
}
}
// for some reason there are 2 extra bytes on the end
stdin.write(buffer, 0, bytesRead-2);
System.out.println("[IN] " + new String(buffer, 0, bytesRead-2) + " [/IN]");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
What I want to do is, launch a .exe console program with Java, and use Java to manipulate the input and output streams from the console window. I know I can get the input and output streams from an application, and this is how I am currently doing it:
try {
process = Runtime.getRuntime().exec("C:\\Users\\Owner\\Documents\\testApp\\console.exe");
} catch (IOException e1) {
e1.printStackTrace();
return;
}
stdin = process.getOutputStream();
stdout = process.getInputStream();
Then, I can use a BufferedReader to show output that the .exe would normally display, however I cannot figure out how to pass input from the Java application console program to the actual .exe input stream. I need some help with how to do this.
Edit:
Ok, I now have this, which works concurrently; however, I can't seem to get any output related to any input I take from the Java console window.
new Thread(new Runnable() {
public void run() {
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
try {
while ((line = br.readLine()) != null) {
System.out.println("[OUT] " + line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
public void run() {
try {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = System.in.read(buffer)) != -1) {
for(int i = 0; i < buffer.length; i++) {
int intValue = new Byte(buffer[i]).intValue();
if (intValue == 0) {
bytesRead = i;
break;
}
}
// for some reason there are 2 extra bytes on the end
stdin.write(buffer, 0, bytesRead-2);
System.out.println("[IN] " + new String(buffer, 0, bytesRead-2) + " [/IN]");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以创建另一个不断从 Java 控制台读取数据的线程,将其重新写入进程的标准输入:
You can create another thread that constantly reads from Java's console, re-writing it to the process's standard input:
首先,您需要同时使用 stdout/stderr (通过单独的线程)。否则,您可以阻止生成的进程,因为您没有消耗其输出。有关更多详细信息,请参阅此答案。
要写入进程,我将用
BufferedWriter
包装stdin
OutputStream
,然后简单地从System.in< 写入该进程。 /代码>
Firstly, you need to be consuming stdout/stderr concurrently (via separate threads). Otherwise you can block your spawned process since you're not consuming its output. See this answer for more details.
To write to the process, I would wrap the
stdin
OutputStream
with aBufferedWriter
, and simply write to that fromSystem.in
使用 ProcessBuilder API。它有非常方便的选项来连接 stderr 和 stdout 流,因此您不必使用多个线程从流中读取数据。
是你的朋友吗?
如果要向进程传递数据:
要读取数据:
请注意以下事项: 如果输入数据超出了进程可以缓冲的范围,并且如果进程已经填满了其输出缓冲区,并且您不从输出缓冲区,您将遇到典型的死锁情况。在这种情况下,您要么必须在单独的进程中读取进程的输出并自己缓冲它,要么让进程首先将数据重定向到临时文件,然后在第二步中读取它。第一个变体的性能更高,但第二个变体更容易理解,如果有大量数据并且性能不重要,也可能是一个有效的选择。
Use the ProcessBuilder API. It has the very convenient option to join stderr and stdout streams, so you don't have to use multiple threads to read from the streams.
is your friend here.
If you want to pass data to the process:
To read data:
Please be aware of the following: If the input data is more than the process can buffer, and if the process already filled its output buffer, and you do not read from the output buffer, you will have a classic deadlock situation. In this case you either have to read output of the process in a separate process and buffer it yourself, or you make the process redirecting the data to a temporary file first, and read this in in a second step. The first variant is more performant, but the second is more easy to understand and might also be a valid option if there is much of data and performance doesn't count.