如何在Java中运行外部Java程序并正确传入文本文件输入?
问题:Java自动化运行外部程序时无法传入输入文件内容
我正在编写一个简易在线评测系统,需要实现用户提交代码的自动化测试,流程如下:
- 用户编写解题程序(例如计算数字平方的程序);
- 为该程序提供输入文件(每个测试用例对应一个,如input.txt),将程序输出与预期输出对比以验证正确性。
示例用户代码(Java):
import java.util.Scanner; public class B { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); System.out.println(n * n); } }
在终端中运行该程序时,执行以下命令可正常读取input.txt的输入:
$ javac B.java $ java B < input.txt
其中input.txt内容为:
5
但使用Java代码自动化运行时,如下代码无法正常工作:
// 为简洁省略大部分代码 public class A { public static void main(String[] args) { // 无法将input.txt传入B类的Scanner,文件被忽略 Process processRun = Runtime.getRuntime().exec("java B < input.txt"); } }
此时input.txt被完全忽略,B类的Scanner会无限等待输入。请问如何通过Java代码正确将input.txt的内容传入B类程序?
解决方案
方法1:通过系统Shell执行命令
Java的Runtime.exec()不会解析Shell的重定向符号(<),因为它直接启动目标进程,而非通过Shell处理命令。因此可以把整个命令交给Shell执行:
Windows系统:
Process process = Runtime.getRuntime().exec("cmd /c java B < input.txt");
Linux/macOS系统:
Process process = Runtime.getRuntime().exec(new String[]{"bash", "-c", "java B < input.txt"});
这种方式让Shell处理输入重定向,和终端执行逻辑完全一致,能正确将input.txt内容传入目标程序。
方法2:手动读取文件并写入子进程输入流
如果需要跨平台兼容性或更灵活的控制,可以自行读取input.txt内容,写入子进程的标准输入流:
import java.io.*; import java.nio.file.Files; public class A { public static void main(String[] args) throws IOException { // 启动目标程序进程 Process process = Runtime.getRuntime().exec("java B"); // 读取input.txt内容 File inputFile = new File("input.txt"); String inputContent = new String(Files.readAllBytes(inputFile.toPath())); // 将内容写入子进程的标准输入流 try (OutputStream os = process.getOutputStream()) { os.write(inputContent.getBytes()); os.flush(); } // 后续可处理子进程输出、等待进程结束等操作 // ... } }
这种方式不依赖Shell环境,适合跨平台的在线评测系统,还能直接处理内存中的测试用例内容,无需依赖物理文件。
内容的提问来源于stack exchange,提问作者aleks
相关产品推荐
相关产品推荐

