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

Java中通过Runtime启动带Scanner.nextLine输入的class时无法输入如何解决

问题根因

  • 通过Runtime.exec启动的子进程拥有独立的标准输入/输出/错误流,默认不会和父进程的控制台绑定,父进程控制台输入的内容无法直接传递给子进程的System.in
  • 现有代码的执行逻辑是先同步读取子进程的标准输出,但子进程此时卡在Scanner.nextLine()等待输入,没有输出内容生成,导致父子进程死锁:父进程等子进程输出,子进程等父进程传入输入

修复方案

核心修改点

  1. 通过Process.getOutputStream()获取子进程标准输入对应的输出流,往这个流写入的内容会直接传入子进程的System.in
  2. 开独立线程分别读取子进程的标准输出和错误输出,避免流缓冲区满导致子进程阻塞
  3. 写入输入内容时必须补充换行符并手动刷新缓冲区,匹配Scanner.nextLine()的读取结束规则

修复后完整代码

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

public class RunExternalApp {
    //Run App from Path
    public static void runApp(String path) throws IOException, InterruptedException {
        Runtime runTime = Runtime.getRuntime();
        Process process = runTime.exec(path);

        // 单独线程处理子进程标准输出
        Thread outputThread = new Thread(() -> {
            try (InputStream inputStream = process.getInputStream();
                 InputStreamReader isr = new InputStreamReader(inputStream)) {
                int n1;
                char[] c1 = new char[1024];
                StringBuffer standardOutput = new StringBuffer();
                while ((n1 = isr.read(c1)) > 0) {
                    standardOutput.append(c1, 0, n1);
                }
                System.out.println("Standard Output: " + standardOutput.toString());
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

        // 单独线程处理子进程错误输出,避免缓冲区满阻塞进程
        Thread errorThread = new Thread(() -> {
            try (InputStream errorStream = process.getErrorStream();
                 InputStreamReader esr = new InputStreamReader(errorStream)) {
                int n2;
                char[] c2 = new char[1024];
                StringBuffer errorOutput = new StringBuffer();
                while ((n2 = esr.read(c2)) > 0) {
                    errorOutput.append(c2, 0, n2);
                }
                System.out.println("Error Output: " + errorOutput.toString());
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

        outputThread.start();
        errorThread.start();

        // 向子进程传入输入,二选一即可
        // 方案1:自动传入固定内容,无需手动输入
        try (OutputStream os = process.getOutputStream();
             BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os))) {
            bw.write("测试输入内容");
            bw.newLine(); // 必须加,匹配Scanner.nextLine()的换行结束规则
            bw.flush(); // 必须加,确保内容写入管道而非留在缓冲区
        }

        // 方案2:转发父进程控制台输入到子进程,需要手动在控制台输入内容
        /*
        try (OutputStream os = process.getOutputStream();
             BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
             Scanner parentScanner = new Scanner(System.in)) {
            String input = parentScanner.nextLine();
            bw.write(input);
            bw.newLine();
            bw.flush();
        }
        */

        // 等待子进程执行结束、流处理完成
        process.waitFor();
        outputThread.join();
        errorThread.join();
    }

    //Main Method
    public static void main(String[] args) throws IOException, InterruptedException {
        String path = "java -classpath E:\\code\\java\\ctppmhw\\bin\\ App";
        runApp(path);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 17:54:05