简体   繁体   中英

Java program using ProcessBuilder with input and output streams doesn't work

I have searched through similar questions here on Stack Overflow, however, I can't seem to make this work.

I have a java program that must use ProcessBuilder to load a C executable file. The file just accepts a string through the CLI and converts it to upper case. The java program creates a system process with ProcessBuilder to manage this executable, and must send the string and receive the converted one to print it in the CLI.

This is the code for 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;
}

I compiled it using

$ gcc uppercases.c -o uppercases

And ran it with

$ ./uppercases

Everything works fine. Now this is the code for Uppercase.java . I have to create an OutputStream to send the string to the C executable (uppercases), and then I create an InputStream to save its output and print it to the 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());
    }
  }
}

To compile, I type:

$ javac Uppercase.java

And to execute:

$ java Uppercase ./uppercases

The problem is that when I type a string and hit enter, the cursor stays forever there, I hit enter again and nothing happens, and finally I have to press CTRL+C to exit. Any help will be appreciated.

All works fine with your java program with one exception : you use a BufferedWriter that you correctly flush, but as the line that you write does not contain a newline, the C program still waits for more input.

If you write :

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

It is enough and the program terminates normally.

But if you really want the things to be bullet proof, you should close bw to clearly indicate to the subprocess that is should not wait for more input :

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

Then the program terminates normally (and correctly) even without the end new line. Of course in that case the last os.close() is no longer necessary but is still harmless.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM