You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python调用Java程序时模拟输入内容未在输出中显示的问题

问题

我正在编写一个用于评分Hangman.java文件的Python脚本。该Java程序通过控制台要求用户猜测字母,正常运行时用户在控制台输入猜测内容即可。我用Python脚本通过输入文件(每行一个猜测内容)模拟用户输入,目前已成功将输入文件内容重定向到Java程序,并能保存Java程序的输出(用于与标准输出比对)。但存在问题:Python脚本模拟输入的字符未在Java程序的输出中显示,例如实际输出为:

Enter your next guess:
You guessed T.
而预期输出为:
Enter your next guess: T
You guessed T.

以下是我的Python脚本:

import subprocess
import sys
import os

def run_java_with_input(java_file, input_file, output_file):
    subprocess.run(['javac', java_file + '.java'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
    os.makedirs(os.path.dirname(output_file), exist_ok=True)
    with open(input_file, 'r') as inputs, open(output_file, 'w') as output:
        process = subprocess.Popen(['java', java_file], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)

        for line in inputs:
            process.stdin.write(line)
            process.stdin.flush()

        out, err = process.communicate()
        output.write(out)

if __name__ == "__main__":
    run_java_with_input(sys.argv[1], sys.argv[2], sys.argv[3])
解决方案

问题核心原因:当Java程序的标准输入被重定向为管道时,操作系统不会自动回显输入内容到标准输出——而控制台交互时,系统会默认完成回显。因此需要在Python脚本中手动模拟这个回显行为。

修改思路

  • 实时监听Java程序的输出,当检测到输入提示行时,先将提示行写入输出文件,再写入对应的输入内容(模拟控制台回显),最后把输入传给Java进程
  • 启用行缓冲,确保能实时读取Java程序的输出,避免内容顺序混乱

修改后的脚本

import subprocess
import sys
import os

def run_java_with_input(java_file, input_file, output_file):
    # 编译Java文件
    subprocess.run(['javac', java_file + '.java'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
    os.makedirs(os.path.dirname(output_file), exist_ok=True)

    with open(input_file, 'r') as inputs, open(output_file, 'w') as output:
        # 启动Java进程,设置行缓冲保证实时读取输出
        process = subprocess.Popen(
            ['java', java_file],
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            text=True,
            bufsize=1
        )

        # 提前读取所有输入行,按顺序匹配输入提示
        input_lines = [line.rstrip('\n') for line in inputs]
        input_idx = 0

        # 实时读取输出并处理输入
        while True:
            output_line = process.stdout.readline()
            if not output_line and process.poll() is not None:
                break

            # 写入Java程序的输出到文件
            output.write(output_line)
            output.flush()

            # 检测到输入提示时,写入输入内容并回显
            if "Enter your next guess:" in output_line:
                if input_idx < len(input_lines):
                    guess = input_lines[input_idx]
                    # 模拟控制台回显输入内容
                    output.write(f"{guess}\n")
                    output.flush()
                    # 将输入传给Java进程
                    process.stdin.write(f"{guess}\n")
                    process.stdin.flush()
                    input_idx += 1

        # 处理进程结束后的剩余输出
        remaining_output = process.communicate()[0]
        if remaining_output:
            output.write(remaining_output)

if __name__ == "__main__":
    run_java_with_input(sys.argv[1], sys.argv[2], sys.argv[3])

关键修改点

  • 设置bufsize=1启用行缓冲,确保实时读取Java程序的输出行
  • 按顺序匹配输入提示和输入内容,保证输出顺序与控制台交互一致
  • 手动回显输入内容到输出文件,还原控制台交互时的输出格式

内容的提问来源于stack exchange,提问作者meep

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 18:43:08