【问题标题】:Programatically interact with an I/O program in Java以编程方式与 Java 中的 I/O 程序交互
【发布时间】:2015-10-27 19:57:17
【问题描述】:

我正在编写一个使用第三方数学软件“Maxima”的程序。该程序是一个命令行界面,因此它可以通过我的 Java 程序通过简单的 I/O 路由进行通信。我已经弄清楚如何从 Java 中运行程序,并且我已经阅读了很多关于如何重新配置​​ System.out 以及 InputStreams/OutputStreams 如何工作的内容,但我不知道如何执行以下操作(我认为应该是一个非常简单的任务):

  1. 从 Java 向 Maxima 输出一个命令,(如字符串“5 + 5;”)
  2. 检索 Maxima 的输出,并从 Java 代码中处理它(比如打印给定的字符串 + “blah”)。
  3. 从 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 ,那么我应该使用BufferedReader r = new BufferedReader(new InputStreamReader( process.getInputStream())); 之类的东西来创建一个可以“读取”Maxima 输出的工具吗?
  • 好的,我现在正在使用该流程开发解决方案,如果我可以让它发挥作用,我一定会发布我的结果作为答案。感谢您的帮助。

标签: java stdout stdin maxima


【解决方案1】:

感谢@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();
    }
}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-31
    • 2012-08-04
    • 2015-07-21
    • 2018-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多