使用来自 Java 的 stdin/out 与 C 程序通信

Communicate with C program using stdin/out from Java

我想让我的 Java 程序与 C 程序通信。这只是一个简单的示例,但我无法使其正常工作。 Java 程序应该 运行 C 程序并写入其输入流。 C 程序应该看到这一点并写入 stdout 作为响应。最后,Java 程序应该从 C 程序的标准输出中读取这个响应并将其打印到屏幕上。

运行 来自命令行的 C 程序我得到了所需的行为。但是,当 Java 程序中的 运行 时,它只是 "hangs" 并且什么都不做。 Java 程序似乎已将其消息写入 C 程序的标准输入,但在 C 程序中看不到此消息。

我将 C 程序设置为将它读取的消息写入文件只是为了检查它是否读取了消息,但它并没有这样做。

这是 C 程序:

#include <stdio.h>
#include <string.h>

void hello();
void wrong();

int main() {
    char buff[256];

    /* 1. read stdin */
    fscanf(stdin, "%s", buff);

    /* side effect - if message was received it should be 
        printed to file */
    FILE *fp = fopen("file.txt", "w");
    fprintf(fp, "%s", buff);
    fclose(fp);

    /* 2. depending on message, write something to stdout */
    if(strcmp(buff, "hello") == 0) {
        hello();
    } else {
        wrong();
    }
}

void hello() {
    printf("Hello World!");
}

void wrong() {
    printf("WRONG!");
}

这里是 Java 程序:

import java.io.*;

public class Main {
    public static void main(String[] args) {
        try {
            // 1. run C program
            Process proc = Runtime.getRuntime().exec("./hello");
            InputStream in = proc.getInputStream();
            OutputStream out = proc.getOutputStream();
            // 2. write 'hello' to 'hello' program
            writeToProc(out, "hello");
            // 3. read response
            readFromProc(in);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    // write message to process
    public static void writeToProc(OutputStream out, String msg) throws IOException {
        byte[] buff = msg.getBytes();
        out.write(buff);
        out.flush();
        System.out.println("done writing: " + new String(buff));
    }

    // read stdin of process
    public static void readFromProc(InputStream in) throws IOException {
        byte[] buff = new byte[256];
        int read = in.read();
        for(int i=0; read != -1; i++) {
            read = in.read();
            buff[i] = (byte) read;
        }
        String str = new String(buff);
        System.out.println("proc says: " + str);
    }
}

当我 运行 Main 时,我得到以下输出:

$ java Main
  done writing: hello

然后只有一个闪烁的光标和文件 "file.txt" 没有写入,表明 C 程序没有从标准输入中读取 "hello"。

这是一个简单的例子,所以我想我遗漏了一些简单的东西或者以某种方式错误地解决了这个问题。

问题是您忘记将换行符 \n 添加到您从 Java 发送的字符串中,因此 fscanf 一直在无限期地等待 "press enter"。我对代码做了一些修改,这些更改记录在注释中。

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Main {
    public static void main(String[] args) {
        try {
            // 1. run C program
            Process proc = Runtime.getRuntime().exec("./hello");
            InputStream in = proc.getInputStream();
            OutputStream out = proc.getOutputStream();
            // 2. write 'hello' to 'hello' program
            // <change>
            // don't forget to add the new line here or in the 
            // writeToProc method
            writeToProc(out, "hello\n");
            // 3. read response
            readFromProc(in);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    // write message to process
    public static void writeToProc(OutputStream out, String msg) throws IOException {
        // <change>
        // Using UTF-8 encoding since all chars in C are byte sized
        byte[] buff = msg.getBytes("UTF-8");
        out.write(buff);
        out.flush();
        System.out.println("done writing: " + new String(buff));
    }

    // read stdin of process
    public static void readFromProc(InputStream in) throws IOException {
        byte[] buff = new byte[256];
        int read = in.read();
        int index = 0;
        while(read != -1) {
            buff[index] = (byte) read;
            read = in.read();
            ++index;
        }
        String str = new String(buff, 0, index);
        System.out.println("proc says: " + str);
    }
}