Spring Boot中执行带输入重定向的Java命令遇阻问题
解决Spring Boot中Runtime.exec无法处理输入重定向的问题
问题原因
Runtime.getRuntime().exec()不会启动系统Shell解析命令,而是直接将整个字符串拆分为命令和参数。你代码里的< D:/input.txt会被当成java命令的参数,而非输入重定向指令,导致子进程一直等待手动输入,无法读取文件内容。
解决方案
方案1:通过系统Shell执行命令(适配系统环境)
借助系统Shell来解析重定向符号,Windows环境用cmd /c,Linux/macOS用bash -c:
// Windows环境 String command = "cmd /c java D:/code.java < D:/input.txt"; Process process = Runtime.getRuntime().exec(command); // Linux/macOS环境 // String command = "bash -c 'java /path/code.java < /path/input.txt'"; // Process process = Runtime.getRuntime().exec(command);
方案2:手动写入子进程输入流(跨平台通用)
不依赖Shell重定向,自己读取输入文件内容并写入子进程的输入流:
String command = "java D:/code.java"; Process process = Runtime.getRuntime().exec(command); // 将input.txt内容写入子进程输入流 try (OutputStream processInput = process.getOutputStream(); FileInputStream fileInput = new FileInputStream("D:/input.txt")) { byte[] buffer = new byte[1024]; int readLen; while ((readLen = fileInput.read(buffer)) != -1) { processInput.write(buffer, 0, readLen); } processInput.flush(); processInput.close(); // 关闭输入流,通知子进程输入结束 } catch (IOException e) { e.printStackTrace(); } // 处理子进程输出流,避免缓冲区满导致阻塞 new Thread(() -> { try (InputStream is = process.getInputStream()) { is.transferTo(System.out); // 可按需替换为自定义处理逻辑 } catch (IOException e) { e.printStackTrace(); } }).start(); // 处理子进程错误流 new Thread(() -> { try (InputStream es = process.getErrorStream()) { es.transferTo(System.err); // 可按需替换为自定义处理逻辑 } catch (IOException e) { e.printStackTrace(); } }).start(); // 等待子进程执行完成 try { int exitCode = process.waitFor(); System.out.println("子进程退出码:" + exitCode); } catch (InterruptedException e) { e.printStackTrace(); }
注意事项
- 必须处理子进程的输出流和错误流,否则子进程输出过多时会因缓冲区溢出阻塞,进而导致主进程卡住。
- 方案1依赖系统Shell,跨平台需区分环境;方案2不受系统限制,通用性更强。
内容的提问来源于stack exchange,提问作者Gaurav kedia
相关产品推荐
相关产品推荐

