收起左侧

    [技术分享] 用Runtime.getRuntime().exec()需要注意的地方

    0
    回复
    396
    查看
    [复制链接]

    管理员

    3374

    主题

    3421

    帖子

    1万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    15115
    发表于 2023-12-27 21:02:36 | 显示全部楼层 |阅读模式
    有时候我们可能需要调用系统外部的某个程序,此时就可以用Runtime.getRuntime().exec()来调用,他会生成一个新的进程去运行调用的程序。
    此方法返回一个java.lang.Process对象,该对象可以得到之前开启的进程的运行结果,还可以操作进程的输入输出流。
    Process对象有以下几个方法:
      1、destroy()      杀死这个子进程
      2、exitValue()      得到进程运行结束后的返回状态
      3、waitFor()       得到进程运行结束后的返回状态,如果进程未运行完毕则等待知道执行完毕
      4、getInputStream()  得到进程的标准输出信息流
      5、getErrorStream()  得到进程的错误输出信息流
      6、getOutputStream() 得到进程的输入流

    现在来讲讲exitValue(),当线程没有执行完毕时调用此方法会跑出IllegalThreadStateException异常,最直接的解决方法就是用waitFor()方法代替。
    但是waitFor()方法也有很明显的弊端,因为java程序给进程的输出流分配的缓冲区是很小的,有时候当进程输出信息很大的时候回导致缓冲区被填满,如果不及时处理程序会阻塞。如果程序没有对进程的输出流处理的会就会导致执行exec()的线程永远阻塞,进程也不会执行下去直到输出流被处理或者java程序结束。
    解决的方法就是处理缓冲区中的信息,开两个线程分别去处理标准输出流和错误输出流。
    程序如下:
    public class ExecTest {        public static void main(String[] args) throws IOException, InterruptedException {      String cmd = "cmd /c dir c:\\windows";      final Process process = Runtime.getRuntime().exec(cmd);      printMessage(process.getInputStream());      printMessage(process.getErrorStream());      int value = process.waitFor();      System.out.println(value);    }        private static void printMessage(final InputStream input) {      new Thread(new Runnable() {         public void run() {            Reader reader = new InputStreamReader(input);            BufferedReader bf = new BufferedReader(reader);            String line = null;             try {                while((line=bf.readLine())!=null) {                    System.out.println(line);                }             } catch (IOException e) {                e.printStackTrace();             }         }      }).start();    }}

    如上程序,读取进程的输出信息并打印到控制台就不会发生阻塞,程序能正常的结束。

    tips:
      cmd命令不能需要加上cmd /c才能执行,不然java会去path中找dir.exe
      在windows一般字符集编码为GBK,需要在转换成Reader的时候指定为GBK编码.

    温馨提示:
    1、本站所有信息都来源于互联网有违法信息与本网站立场无关。
    2、当有关部门,发现本论坛有违规,违法内容时,可联系站长删除,否则本站不承担任何责任。
    3、当政府机关依照法定程序要求披露信息时,论坛均得免责。
    4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
    5、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
    6、如果使用本帖附件,本站程序只提供学习使用,请24小时内删除!使用者搭建运营触犯法律,违法,违规,本站不承担任何责任。
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    在线客服
    热线电话

    微信扫一扫
    专注源码分享6年
    全国免费热线电话

    400-225-995

    周一至周日9:00-23:00

    反馈建议

    a5887776@163.com 在线QQ咨询

    Powered by Discuz! X3.4 Licensed © 2001-2013 Comsenz Inc.