以编程方式与 Java 中的 I/O 程序交互
Programatically interact with an I/O program in Java
我正在编写一个利用第三方数学软件的程序,"Maxima"。该程序是一个命令行界面,因此它可以通过我的 Java 程序与简单的 I/O 路由进行通信。我已经弄清楚如何从 Java 中 运行 程序,并且我已经阅读了很多关于如何重新配置 System.out 以及 InputStreams/OutputStreams 如何工作的内容,但是我可以不知道如何执行以下操作(我认为应该是一项非常简单的任务):
- 向 Maxima 输出来自 Java 的命令(如字符串“5 + 5;”)
- 检索 Maxima 的输出,并从 Java 代码处理它(比如打印给定的字符串 + "blah")。
- 从 Java...
向 Maxima 输出另一个命令
- 等等
-
下面是 运行 Maxima 并允许我在 Eclipse 控制台上与它交互的代码
public static void main(final String[] args) {
// An idea I had for manipulaing how the printstream works.
// Set the system.out to be a custom Prinstream.
// final PrintStream interceptor = new Interceptor(origOut);
// System.setOut(interceptor);
// Run the program:
final String programLocation = "\"C:\Program Files (x86)\Maxima-sbcl-5.37.2\bin\maxima.bat\"";
final ProcessBuilder pb = new ProcessBuilder();
pb.redirectInput(Redirect.INHERIT); // Inherit I/O
pb.redirectOutput(Redirect.INHERIT);
pb.command(programLocation);
try {
// Start the program and allow it to run in Eclipse's/the program's
// console.
pb.start().waitFor();
} catch (final InterruptedException e) {
e.printStackTrace();
} catch (final IOException e) {
e.printStackTrace();
}
}
这允许以下交互方式:
感谢@RealSkeptic 的智慧之言,我想我在这里找到了解决方案。
关键是构建一个 BufferedWriter 和一个 BufferedReader 来与 Maxima 的 I/O 进行交互。即:
BufferedWriter w = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
BufferedReader r = new BufferedReader(new InputStreamReader(process.getInputStream()));
这两行代码创建了缓冲的读取器和写入器,它们可以将数据输入到 Maxima,并读取 Maxima 的输出。这是此方法的一个(相当长的)用例,我基本上用它来做我在问题中提出的问题:
public class TestClass {
public static void main(final String[] args) {
@SuppressWarnings("unused")
final TestClass ts = new TestClass();
}
private BufferedWriter w;
private BufferedReader r;
public TestClass() {
// Start the process using process builder
final String programLocation = "\"C:\Program Files (x86)\Maxima-sbcl-5.37.2\bin\maxima.bat\"";
final ProcessBuilder pb = new ProcessBuilder();
pb.command(programLocation);
Process process;
try {
process = pb.start();
} catch (final IOException e) {
e.printStackTrace();
process = null;
// killProgram();
}
// Build your own wrappers for communicating with the program.
w = new BufferedWriter(
new OutputStreamWriter(process.getOutputStream()));
r = new BufferedReader(new InputStreamReader(process.getInputStream()));
// Print the five starting messages.
printFromBuffer();
printFromBuffer();
printFromBuffer();
printFromBuffer();
printFromBuffer();
// Run the following three commands in Maxima
runCommand("5+5;");
runCommand("2*65;");
runCommand("quit();");
}
/**
* Runs the given string and prints out the returned answer.
*/
private void runCommand(final String s) {
try {
w.write(s);
w.flush();
printFromBuffer();
printFromBuffer();
} catch (final IOException e) {
e.printStackTrace();
}
}
private void printFromBuffer() {
try {
final String s = r.readLine();
System.out.println(s + " -blah");
} catch (final IOException e) {
System.err.println(e.getMessage());
e.printStackTrace();
}
}
}
我正在编写一个利用第三方数学软件的程序,"Maxima"。该程序是一个命令行界面,因此它可以通过我的 Java 程序与简单的 I/O 路由进行通信。我已经弄清楚如何从 Java 中 运行 程序,并且我已经阅读了很多关于如何重新配置 System.out 以及 InputStreams/OutputStreams 如何工作的内容,但是我可以不知道如何执行以下操作(我认为应该是一项非常简单的任务):
- 向 Maxima 输出来自 Java 的命令(如字符串“5 + 5;”)
- 检索 Maxima 的输出,并从 Java 代码处理它(比如打印给定的字符串 + "blah")。
- 从 Java... 向 Maxima 输出另一个命令
- 等等
- 下面是 运行 Maxima 并允许我在 Eclipse 控制台上与它交互的代码
public static void main(final String[] args) {
// An idea I had for manipulaing how the printstream works.
// Set the system.out to be a custom Prinstream.
// final PrintStream interceptor = new Interceptor(origOut);
// System.setOut(interceptor);
// Run the program:
final String programLocation = "\"C:\Program Files (x86)\Maxima-sbcl-5.37.2\bin\maxima.bat\"";
final ProcessBuilder pb = new ProcessBuilder();
pb.redirectInput(Redirect.INHERIT); // Inherit I/O
pb.redirectOutput(Redirect.INHERIT);
pb.command(programLocation);
try {
// Start the program and allow it to run in Eclipse's/the program's
// console.
pb.start().waitFor();
} catch (final InterruptedException e) {
e.printStackTrace();
} catch (final IOException e) {
e.printStackTrace();
}
}
这允许以下交互方式:
感谢@RealSkeptic 的智慧之言,我想我在这里找到了解决方案。
关键是构建一个 BufferedWriter 和一个 BufferedReader 来与 Maxima 的 I/O 进行交互。即:
BufferedWriter w = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
BufferedReader r = new BufferedReader(new InputStreamReader(process.getInputStream()));
这两行代码创建了缓冲的读取器和写入器,它们可以将数据输入到 Maxima,并读取 Maxima 的输出。这是此方法的一个(相当长的)用例,我基本上用它来做我在问题中提出的问题:
public class TestClass {
public static void main(final String[] args) {
@SuppressWarnings("unused")
final TestClass ts = new TestClass();
}
private BufferedWriter w;
private BufferedReader r;
public TestClass() {
// Start the process using process builder
final String programLocation = "\"C:\Program Files (x86)\Maxima-sbcl-5.37.2\bin\maxima.bat\"";
final ProcessBuilder pb = new ProcessBuilder();
pb.command(programLocation);
Process process;
try {
process = pb.start();
} catch (final IOException e) {
e.printStackTrace();
process = null;
// killProgram();
}
// Build your own wrappers for communicating with the program.
w = new BufferedWriter(
new OutputStreamWriter(process.getOutputStream()));
r = new BufferedReader(new InputStreamReader(process.getInputStream()));
// Print the five starting messages.
printFromBuffer();
printFromBuffer();
printFromBuffer();
printFromBuffer();
printFromBuffer();
// Run the following three commands in Maxima
runCommand("5+5;");
runCommand("2*65;");
runCommand("quit();");
}
/**
* Runs the given string and prints out the returned answer.
*/
private void runCommand(final String s) {
try {
w.write(s);
w.flush();
printFromBuffer();
printFromBuffer();
} catch (final IOException e) {
e.printStackTrace();
}
}
private void printFromBuffer() {
try {
final String s = r.readLine();
System.out.println(s + " -blah");
} catch (final IOException e) {
System.err.println(e.getMessage());
e.printStackTrace();
}
}
}