如何使用Python执行带有输入输出的Java程序

4 投票
1 回答
23444 浏览
提问于 2025-04-17 13:11

假设我的 Python 程序叫做 input.py

import os.path,subprocess
from subprocess import STDOUT,PIPE

def compile_java(java_file):
subprocess.check_call(['javac', java_file])

def execute_java(java_file):
java_class,ext = os.path.splitext(java_file)
cmd = ['java', java_class]
proc = subprocess.Popen(cmd,stdout=PIPE,stderr=STDOUT)
input=subprocess.Popen(cmd,stdin=PIPE)
print proc.stdout.read()

我使用的 Java 文件是 Hi.java

import java.util.*;
class Hi
{
       public static void main(String args[])
       {
            Scanner t=new Scanner(System.in);
            System.out.println("Enter any string");
            String str=t.nextLine();
            System.out.println("This is "+str);
            int a=5;
            System.out.println(a);
       }
}

当我调用 input.execute_java(Hi.java) 时,输出是 "Enter the string",然后当我输入字符串,比如 "Jon",它又打印出 "Enter the string This is Jon",也就是说,输出内容重复了两次。可能第一次输出是因为 Python 代码 input=subprocess.Popen(cmd,stdin=PIPE),第二次输出是因为代码 print proc.stdout.read()。我希望输出只打印一次。我想让我的 Python 变量接收到 Java 程序的所有输出,然后用这个变量在屏幕上显示输出。如果 Java 程序需要输入,我希望用户输入的内容能存储在我的 Python 变量中,并且用这个变量把输入传递给 Java 程序。我该怎么做呢?

1 个回答

8

你应该使用 communicate,而不是 stdout.readcommunicate 的参数是你要传给子进程的输入。而且,如果你并不想让命令通过一个 shell 来执行,使用 shell=True 是个坏主意。相反,应该把参数作为一个列表传递:

import os.path,subprocess
from subprocess import STDOUT,PIPE

def compile_java(java_file):
    subprocess.check_call(['javac', java_file])

def execute_java(java_file, stdin):
    java_class,ext = os.path.splitext(java_file)
    cmd = ['java', java_class]
    proc = subprocess.Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
    stdout,stderr = proc.communicate(stdin)
    print ('This was "' + stdout + '"')

compile_java('Hi.java')
execute_java('Hi.java', 'Jon')

撰写回答