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

时间:2017-04-23 22:48:30

标签: java c stdout stdin

我希望我的Java程序与C程序通信。这只是一个简单的例子,但我不能让它工作。 Java程序应该运行C程序并写入其输入流。 C程序应该看到这个并写入stdout作为响应。最后,Java程序应该从C程序的标准输出读取此响应并将其打印到屏幕上。

从命令行运行C程序我得到了所需的行为。但是,当从Java程序运行时,它只是“挂起”并且什么都不做。 Java程序似乎已将其消息写入C程序的stdin,但此消息在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程序没有从stdin读取“hello”。

这是一个简单的例子,所以我想我错过了一些简单的东西或以某种方式以错误的方式来到这里。

1 个答案:

答案 0 :(得分:3)

问题是您忘记将新行字符\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);
    }
}