• windows下Java调用可执行文件


     缘起:

      由于没有找到java转换文件的接口,因此使用java调用exe文件进行文件转换

    public void convertFile(){
            Runtime rn = Runtime.getRuntime();
            Process p =null;
            try{
                p = rn.exec("D:/convert/Convert.exe D:/convert/my.ifc D:/convert/tmp.dae");
            }catch (Exception e){
                e.printStackTrace();
            }
        }

    调用这个方法,就可以实现文件的转换了,和在命令窗口执行的结果一样

    获取执行结果

    public void convertFile(){
            Runtime rn = Runtime.getRuntime();
            Process p =null;
            try{
                p = rn.exec("D:/convert/Convert.exe D:/convert/my.ifc D:/convert/tmp.dae");int exitVal = p.waitFor();
                if (exitVal == 0) {
                    System.out.println("转换成功.");
                } else {
                    System.out.println( "转换失败.");
                }
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                p.destroy();
            }
    }

    注:

      安全编码规范中都会指出:使用Process.waitfor的时候,可能导致进程阻塞,甚至死锁

      出现挂起的原因为:可执行程序的标准输出比较多,而运行窗口的标准输出缓冲区不够大。

    1.主进程中调用Runtime.exec会创建一个子进程,用于执行程序。子进程创建后会和主进程分别独立运行
    2.主进程需要等待脚本执行完成,然后对执行程序返回值或输出进行处理,所以这里主进程调用Process.waitfor等待子进程完成
    3.子进程执行过程就是不断的打印信息。主进程中可以通过Process.getInputStream和Process.getErrorStream获取并处理
    4.子进程不断向主进程发生数据,而主进程调用Process.waitfor后已挂起。当前子进程和主进程之间的缓冲区塞满后,子进程不能继续写数据,然后也会挂起
    5.子进程等待主进程读取数据,主进程等待子进程结束,两个进程相互等待,最终导致死锁

      解决的办法是,利用Java中Process类提供的方法让Java虚拟机截获被调用程序的DOS运行窗口的标准输出,在waitfor()命令之前读出窗口的标准输出缓冲区中的内容。

       优化代码

    public void convertFile(){
            Runtime rn = Runtime.getRuntime();
            Process p =null;
            try{
                p = rn.exec("D:/convert/Convert.exe D:/convert/my.ifc D:/convert/tmp.dae");
                InputStream stdin = p.getInputStream();
                InputStreamReader isr = new InputStreamReader(stdin);
                BufferedReader br = new BufferedReader(isr);
                String line = null;
                System.out.println("<output>");
                while ((line = br.readLine()) != null)
                    System.out.println(line);
                System.out.println("</output>");
                int exitVal = p.waitFor();
                if (exitVal == 0) {
                    System.out.println("转换成功.");
                } else {
                    System.out.println( "转换失败.");
                }
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                p.destroy();
            }
    }
  • 相关阅读:
    Procedure execution failed 2013
    struts2总结四:Action与Form表单的交互
    JQuery中的DOM操作
    easyui提交表单数据的时候如何防止二次提交
    一句话
    字符串截取函数substr和substring的不同及其相关说明
    四句话
    JAVA定时执行任务,每天定时几点钟执行任务
    JAVA定时执行任务的三种方法
    struts2总结三:struts2配置文件struts.xml的简单总结
  • 原文地址:https://www.cnblogs.com/baby123/p/11018225.html
Copyright © 2020-2023  润新知