Java无法带参数执行外部exe程序的技术求助
解决Java中执行带输入重定向的外部程序问题
我明白你遇到的问题啦——avl < test.ops里的<并不是传给avl的命令行参数,而是操作系统shell的输入重定向语法,直接用ProcessBuilder传递这个参数是不行的,因为ProcessBuilder默认会直接启动目标程序,不会经过shell解析这些特殊语法。下面给你两种可行的解决方案:
方案1:通过系统shell执行命令
我们可以把整个命令交给系统的shell来解析执行,不同操作系统的shell命令略有区别:
Linux/macOS 环境
try { // 用bash -c 来执行带重定向的命令 String[] command = {"/bin/bash", "-c", "avl < test.ops"}; ProcessBuilder pb = new ProcessBuilder(command); Process p = pb.start(); // 读取程序输出的逻辑和你原来的一致 BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); String line; while ((line = br.readLine()) != null) { System.out.println(line); } // 别忘了处理错误输出,避免程序阻塞 BufferedReader errBr = new BufferedReader(new InputStreamReader(p.getErrorStream())); while ((line = errBr.readLine()) != null) { System.err.println(line); } p.waitFor(); } catch (Exception e) { e.printStackTrace(); }
Windows 环境
如果是Windows系统,需要换成cmd /c:
try { String[] command = {"cmd.exe", "/c", "avl < test.ops"}; ProcessBuilder pb = new ProcessBuilder(command); Process p = pb.start(); // 同样的输出读取逻辑 BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); String line; while ((line = br.readLine()) != null) { System.out.println(line); } BufferedReader errBr = new BufferedReader(new InputStreamReader(p.getErrorStream())); while ((line = errBr.readLine()) != null) { System.err.println(line); } p.waitFor(); } catch (Exception e) { e.printStackTrace(); }
注意:如果要跨平台,可以通过System.getProperty("os.name")判断当前系统,再选择对应的shell命令。
方案2:手动实现输入重定向(更推荐,跨平台)
不需要依赖shell,我们可以直接在Java代码中读取test.ops的内容,然后把它写入到外部进程的输入流中,模拟shell的<重定向效果:
try { String[] command = {"avl"}; // 这里只需要传递程序名,不需要重定向参数 ProcessBuilder pb = new ProcessBuilder(command); Process p = pb.start(); // 读取test.ops的内容,写入到外部进程的输入流 try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(p.getOutputStream())); BufferedReader fileBr = new BufferedReader(new FileReader("test.ops"))) { String line; while ((line = fileBr.readLine()) != null) { bw.write(line); bw.newLine(); // 注意换行符,保持文件格式一致 } bw.flush(); // 关闭输入流,告诉外部程序输入已经结束 p.getOutputStream().close(); } // 读取外部程序的输出 BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); String line; while ((line = br.readLine()) != null) { System.out.println(line); } // 处理错误输出 BufferedReader errBr = new BufferedReader(new InputStreamReader(p.getErrorStream())); while ((line = errBr.readLine()) != null) { System.err.println(line); } p.waitFor(); } catch (Exception e) { e.printStackTrace(); }
这种方法的优势是不需要依赖系统shell,代码在任何Java支持的平台上都能运行,而且更可控,你可以自己处理输入的内容(比如修改、过滤后再传给外部程序)。
内容的提问来源于stack exchange,提问作者Dersu Uzala
相关产品推荐
相关产品推荐

