java中的Runtime.exec()挂起,因为它正在等待来自System.in的输入

时间:2016-09-21 09:39:33

标签: java python multithreading process runtime.exec

我有以下短的python程序“test.py”

n = int(raw_input())
print n

我正在执行以下程序来自以下java程序“ProcessRunner.java”

import java.util.*;
import java.io.*;

public class ProcessRunner {
    public static void main(String[] args) {
        try {
            Scanner s = new Scanner(Runtime.getRuntime().exec("python test.py").getInputStream()).useDelimiter("\\A");
            System.out.println(s.next());
        }

        catch(Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

运行命令后,

java ProcessRunner

我无法以适当的格式将值'n'传递给Python程序,而且java run也会挂起。处理这种情况的正确方法是什么,并从java程序中动态地将值传递给'n'到python程序?

2 个答案:

答案 0 :(得分:2)

raw_input()或Python 3中的input()将阻止等待标准输入上的新行终止输入,但Java程序不会发送任何内容。

尝试使用getOutputStream()返回的流写入Python子流程。这是一个例子:

import java.util.*;
import java.io.*;

public class ProcessRunner {
    public static void main(String[] args) {
        try {
            Process p = Runtime.getRuntime().exec("python test.py");
            Scanner s = new Scanner(p.getInputStream());
            PrintWriter toChild = new PrintWriter(p.getOutputStream());

            toChild.println("1234");    // write to child's stdin
            toChild.close();            // or you can use toChild.flush()
            System.out.println(s.next());
        }

        catch(Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

另一种方法是将n作为命令行参数传递。这需要修改Python脚本以期望和处理命令行参数,并且需要Java代码来发送参数:

import java.util.*;
import java.io.*;

public class ProcessRunner {
    public static void main(String[] args) {
        try {
            int n = 1234;
            Process p = Runtime.getRuntime().exec("python test.py " + n);
            Scanner s = new Scanner(p.getInputStream());
            System.out.println(s.next());
        }

        catch(Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

Python脚本test.py

import sys

if len(sys.argv) > 1:
    print int(sys.argv[1]) 

答案 1 :(得分:0)

如果我理解你的正确,你希望你的java程序将你的python脚本的任何输出传递给你的java程序和你的python脚本的任何输入,对吗?

查看以下程序,了解如何执行此操作。

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

public class ProcessRunner {

    public static void main(String[] args) {
        try {
            final Process process = Runtime.getRuntime().exec("/bin/sh");

            try (
                    final InputStream inputStream = process.getInputStream();
                    final InputStream errorStream = process.getErrorStream();
                    final OutputStream outputStream = process.getOutputStream()
            ) {

                while (process.isAlive()) {
                    forwardOneByte(inputStream, System.out);
                    forwardOneByte(errorStream, System.err);
                    forwardOneByte(System.in, outputStream);
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static void forwardOneByte(final InputStream inputStream,
                                       final OutputStream outputStream)
    throws IOException {
        if(inputStream.available() <= 0) {
            return;
        }

        final int b = inputStream.read();
        if(b != -1) {
            outputStream.write(b);
            outputStream.flush();
        }
    }
}

注意此代码只是一个概念演示。它会耗尽您的CPU,并且无法应对更大的吞吐量。