从java运行python脚本并发送输入/输出

时间:2017-12-29 12:39:45

标签: java multithreading python-2.7 stdout stdin

我正在编写一个需要运行python脚本的java程序 该脚本将打印输出,java需要读取该输出以了解脚本的进度 为了能够在运行时暂停脚本,我希望它偶尔请求输入,只有当java给它输入时,脚本才会继续运行。
这是我的Java方法:

private static void sevenTry(String[] strCommands) throws IOException {
    Object oLock1 = new Object();
    Object oLock2 = new Object();

    ProcessBuilder pBuilder = new ProcessBuilder(strCommands);
    pBuilder.redirectErrorStream(true);
    Process proc = pBuilder.start();

    Thread tReader = new Thread() {
        @Override
        public void run() {
            System.out.println("~~tReader starting~~");
            BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            synchronized (oLock1) {
                try {
                    String line = reader.readLine();
                    while (line != null && !line.trim().equals("--EOF--")) {
                        System.out.println("Stdout: " + line);
                        if (line.trim().equals("--INPUT--")) {
                            synchronized (oLock2) {
                                oLock2.notify();
                            }
                            oLock1.wait();
                        }
                        line = reader.readLine();
                    }
                } catch (IOException e) {
                    System.out.println("tReader: " + e.getMessage());
                } catch (InterruptedException e) {
                    System.out.println("tReader: " + e.getMessage());
                } catch (Exception e) {
                    System.out.println("tReader: " + e.getMessage());
                }
            }
            System.out.println("~~tReader end~~");
            synchronized (oLock2) {
                oLock2.notify();
            }
        }
    };
    Thread tWriter = new Thread() {
        @Override
        public void run() {
            System.out.println("~~tWriter starting~~");
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));

            String line, input;
            Scanner scan = new Scanner(System.in);

            synchronized (oLock2) {
                try {
                    oLock2.wait();
                } catch (InterruptedException e1) {
                    System.out.println("tWriter: " + e1.getMessage());
                }
            }
            while (tReader.isAlive()) {
                synchronized (oLock1) {
                    System.out.println("Java: insert input");
                    scan.hasNext();
                    input = scan.nextLine();
                    try {
                        writer.write(input + "\n");
                        writer.flush();
                    } catch (IOException e) {
                        System.out.println("tWriter: " + e.getMessage());
                    }
                    oLock1.notify();
                }
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e1) {
                    System.out.println("tWriter: " + e1.getMessage());
                }
            }
            System.out.println("~~tWriter end~~");
        }
    };

    tReader.start();
    tWriter.start();
    System.out.println("~~everything submitted~~");
    try {
        tReader.join();
        tWriter.join();
        System.out.println("~~finish~~");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

这是我的python脚本:

# coding=utf-8
import sys

print '1'
print '--INPUT--'
inum = sys.stdin.readline()
print '2'
print '--EOF--'

我尝试运行我的代码

sevenTry("python", "C:\\Testing.py");

但是在java方面它会被困在tReader中的行:

String line = reader.readLine();

如果我从python文件中取出输入行

,程序就能正常工作
inum = sys.stdin.readline()

使用

inum = raw_input()

仍然提出同样的问题(即时通讯使用python 2.7)
这里最令人困惑的部分是我甚至试图用java文件(而不是python)测试它(

sevenTry("java", "-classpath", "C:\\class", "CheckCMD");

它甚至可以用输入线

工作
import java.util.Scanner;

public class CheckCMD {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String line;
        System.out.println("1");
        System.out.println("--INPUT--");
        in.hasNext();
        line = in.nextLine();
        System.out.println("2");
        System.out.println("--EOF--");
    }
}

1 个答案:

答案 0 :(得分:0)

您可能已经注意到,这是与Python相关的问题。

https://unix.stackexchange.com/questions/182537/write-python-stdout-to-file-immediately中所述,

"当进程STDOUT被重定向到终端以外的其他东西时,输出被缓冲到某个特定于操作系统的缓冲区(在许多情况下可能是4k或8k)。"

因此,您需要在每次调用sys.stdout.flush()后调用print

或者,作为更好的选择,您可以使用-u param更改进程的默认行为,以获得无缓冲的输出。