Java Runtime.getRuntime().exec 不同的输出格式

Java Runtime.getRuntime().exec different output format

我有一个简单的python程序(hw1.py)如下:

x = int(input("Enter x value: "))
y = int(input("Enter y value: "))

print("x is " + str(x))
print("y is " + str(y))
print("Output is " + str(x+y))

当我从终端 运行 时,我按预期得到以下输出:

Enter x value: 10
Enter y value: 20
x is 10
y is 20
Output is 30

但是,当我从 Java 运行 提供输入(“10”和“20”)时,我得到的输出略有不同。这是要编译的 Java 代码和 运行 python 文件:

String osName = System.getProperty("os.name").toLowerCase();
boolean isMacOs = osName.startsWith("mac os x");
String macPythonPath = "/Library/Frameworks/Python.framework/Versions/3.6/bin/python3";
String unixPythonPath = "/usr/bin/python3";
Process p;
if (isMacOs) {
    p = Runtime.getRuntime().exec(macPythonPath + " -m py_compile " + "/Users/inanc/Desktop/pythonDocs/hw1.py");

} else {
    p = Runtime.getRuntime().exec(unixPythonPath + " -m py_compile " + "/Users/inanc/Desktop/pythonDocs/hw31.py");  
}

BufferedReader stdError = new BufferedReader(new 
        InputStreamReader(p.getErrorStream()));


String resError = "", s;
// read any errors from the attempted command
while ((s = stdError.readLine()) != null) {
    resError = resError + s + "\n";
}
resError = resError.trim();
stdError.close();

if (resError.equals("")) {

    if (isMacOs) {
        p = Runtime.getRuntime().exec(macPythonPath + " " + "/Users/inanc/Desktop/pythonDocs/hw1.py");

    } else {
        p = Runtime.getRuntime().exec(unixPythonPath + " " + "/Users/inanc/Desktop/pythonDocs/hw1.py"); 
    }
    String[] inputs = {"10", "20"};
    OutputStream out = p.getOutputStream();
    for (String input: inputs) {
        if (input.equals("") == false)
            out.write((input+"\n").getBytes());
    }
    out.flush();

    BufferedReader stdInput = new BufferedReader(new 
            InputStreamReader(p.getInputStream()));

    stdError = new BufferedReader(new 
            InputStreamReader(p.getErrorStream()));

    // read the output from the command
    String res = ""; 
    s = null;
    while ((s = stdInput.readLine()) != null) {
        res = res + s + "\n" ;
    }
    res = res.trim();

    resError = "";
    // read any errors from the attempted command
    while ((s = stdError.readLine()) != null) {
        resError = resError + s + "\n";
    }
    resError = resError.trim();
    stdInput.close();
    stdError.close();
    p = null;
    System.out.println(res);
} else {
    System.err.println(resError);
}

调用这段代码后,输出结果如下:

Enter x value: Enter y value: x is 10
y is 20
Output is 30

如何获得与终端执行完全相同的输出?至少我想在输入后保留换行符。

然后只有当你让你的程序将参数 10 写入进程,然后从进程中读取下一行然后将 20 写入进程时,才有一种方法,并且另一行是从进程中读取的,依此类推

然而,在您的代码中,您在单个循环中编写流程所需的所有输入

我解决了这个问题,这里是解决方案:

String osName = System.getProperty("os.name").toLowerCase();
boolean isMacOs = osName.startsWith("mac os x");
String macPythonPath = "/Library/Frameworks/Python.framework/Versions/3.6/bin/python3";
String unixPythonPath = "/usr/bin/python3";
String filepath = "/Users/inanc/Desktop/pythonDocs/hw1additionalInputs.py ";
Process p;
if (isMacOs){
    p = Runtime.getRuntime().exec(macPythonPath + " -m py_compile " + filepath);

}
else{
    p = Runtime.getRuntime().exec(unixPythonPath + " -m py_compile " + filepath);   
}

BufferedReader stdError = new BufferedReader(new 
        InputStreamReader(p.getErrorStream()));


String resError = "", s;
// read any errors from the attempted command
while ((s = stdError.readLine()) != null) {
    resError = resError + s + "\n";
}
resError = resError.trim();
stdError.close();

if(resError.equals("")) {


    if (isMacOs){
        p = Runtime.getRuntime().exec(macPythonPath + " " + filepath);

    }
    else{
        p = Runtime.getRuntime().exec(unixPythonPath + " " + filepath); 
    }

    BufferedReader stdInput = new BufferedReader(new 
            InputStreamReader(p.getInputStream()));

    stdError = new BufferedReader(new 
            InputStreamReader(p.getErrorStream()));

    // read the output from the command
    String res = ""; 
    s = null;
    String[] inputs = {"10", "20"};
    OutputStream out = p.getOutputStream();


    for(String input:inputs){
        if(input.equals("") == false)
        {

            Thread.sleep(200);
            while (stdInput.ready() && (s = "" + (char) stdInput.read()) != null) {
                res = res + s ;

            }

            // read any errors from the attempted command
            Thread.sleep(200);
            while (stdError.ready() && (s = "" + (char) stdError.read()) != null) {
                resError = resError + s;
            }

            if(resError.equals("") == false)
                break;

            out.write((input+"\n").getBytes());
            out.flush();
            res = res + input + "\n";

            Thread.sleep(200);
            while (stdInput.ready() && (s = "" + (char) stdInput.read()) != null) {
                res = res + s ;

            }
            //res = res.trim();

            // read any errors from the attempted command
            Thread.sleep(200);
            while (stdError.ready() && (s = "" + (char) stdError.read()) != null) {
                resError = resError + s;
            }
            if(resError.equals("") == false)
                break;


        }
    }

    Thread.sleep(200);
    while (stdInput.ready() && (s = "" + (char) stdInput.read()) != null) {
        res = res + s ;

    }
    //res = res.trim();

    // this part is for in case of no inputs
    Thread.sleep(200);
    while (stdError.ready() && (s = "" + (char) stdError.read()) != null) {
        resError = resError + s;
    }
    stdInput.close();
    stdError.close();
    if(p.isAlive())
    {
        System.err.println("Timeout");
        p.destroy();
    }
    p = null;
    System.out.println(res);
    System.out.println(resError);
}
else {
    System.err.println(resError);
}