【问题标题】:Java program using ProcessBuilder with input and output streams doesn't work使用带有输入和输出流的 ProcessBuilder 的 Java 程序不起作用
【发布时间】:2023-08-18 20:04:01
【问题描述】:

我在 Stack Overflow 上搜索过类似的问题,但是,我似乎无法完成这项工作。

我有一个必须使用 ProcessBuilder 来加载 C 可执行文件的 java 程序。该文件仅通过 CLI 接受字符串并将其转换为大写。 java 程序使用 ProcessBuilder 创建一个系统进程来管理这个可执行文件,并且必须发送字符串并接收转换后的字符串以在 CLI 中打印它。

这是 uppercases.c 的代码:

#include <stdio.h>

int main(int argc, char *argv[]) {
    char text[1024];
    scanf("%s", &text[0]);

    int i;
    for(i = 0; i < strlen(text); i++) {
        text[i] = toupper(text[i]);
    }

    printf("%s\n", text);
    return 0;
}

我使用它编译它

$ gcc uppercases.c -o uppercases

然后运行它

$ ./uppercases

一切正常。现在这是 Uppercase.java 的代码。我必须创建一个 OutputStream 来将字符串发送到 C 可执行文件(大写),然后我创建一个 InputStream 来保存其输出并将其打印到 CLI:

public class Uppercase {

public static void main(String[] command) {
    String textIn, textOut;
    Scanner reader = new Scanner(System.in);

    // This is what we want to send
    System.out.println("Write something: ");
    textIn = reader.nextLine();

    try {
        // Here I create a process to handle "uppercases"
        Process process = new ProcessBuilder(command).start();

        OutputStream os = process.getOutputStream();
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));

        // According to me, this will send the string to "uppercases"
        bw.write(textIn);
        bw.flush();

        // This is to read the output of "uppercases"
        InputStream is = process.getInputStream();
        BufferedReader br = new BufferedReader (new InputStreamReader(is));

        while ((textOut = br.readLine()) != null) {
             System.out.println(textOut);
        }

        os.close();
        is.close();

    } catch (IOException e) {
        System.out.println("I/O error:" + e.getMessage());
    } catch (Exception e) {
        System.out.println("Error:" + e.getMessage());
    }
  }
}

要编译,我输入:

$ javac Uppercase.java

并执行:

$ java Uppercase ./uppercases

问题是当我输入一个字符串并按回车时,光标永远停留在那里,我再次按回车并没有任何反应,最后我必须按 CTRL+C 退出。任何帮助将不胜感激。

【问题讨论】:

  • 不确定这是否会有所不同,但您可以将输入更改为下一个吗? textIn = reader.next();
  • 添加一些系统输出(在读取输入之后,在启动进程之前等)。能否用 Process builder 调用其他命令(如 echo)?
  • 是的,我会在每个方法/函数中添加一些打印语句,以确保它实际上承认它们
  • 这将有助于在 br 周围添加断点(在初始化期间和使用它时)。这可以告诉你 br 在使用时的值是什么..

标签: java c processbuilder


【解决方案1】:

您的 java 程序一切正常,但有一个例外:您使用了正确刷新的 BufferedWriter,但由于您编写的行不包含换行符,C 程序仍等待更多输入。

如果你写:

// According to me, this will send the string to "uppercases"
bw.write(textIn);
bw.write("\n");
bw.flush();

足够了,程序正常终止。

但是如果你真的希望事情是防弹的,你应该关闭bw 以清楚地指示不应该等待更多输入的子进程:

// According to me, this will send the string to "uppercases"
bw.write(textIn);
bw.close();

然后程序正常(并且正确)终止,即使没有结束新行。当然,在这种情况下,最后一个 os.close() 不再需要,但仍然无害。

【讨论】:

  • 它工作。像一个魅力。非常感谢先生 =D =D =D
最近更新 更多